This is an automated email from the ASF dual-hosted git repository.

solomax pushed a commit to branch OPENMEETINGS-2402-reworked-upload
in repository https://gitbox.apache.org/repos/asf/openmeetings.git

commit 4218027954b26053145b40511678d0f69185afdc
Author: Maxim Solodovnik <solomax...@gmail.com>
AuthorDate: Mon Jul 27 20:31:09 2020 +0700

    [OPENMEETINGS-2402] file upload is re-worked (incomplete)
---
 .../openmeetings/core/remote/BaseMockedTest.java   |   4 +-
 .../openmeetings/db/entity/file/FileItemTest.java  |   4 +-
 .../apache/openmeetings/web/app/Application.java   |   2 +
 .../openmeetings/web/common/OmWebSocketPanel.java  |  23 +--
 .../org/apache/openmeetings/web/common/main.js     |   4 +-
 .../sidebar/RoomFileUploadResourceReference.java   | 218 ++++++++++++++++++++
 .../web/room/sidebar/UploadDialog.html             |  19 +-
 .../web/room/sidebar/UploadDialog.java             | 222 ++-------------------
 .../apache/openmeetings/web/room/sidebar/upload.js |  64 +++++-
 .../web/user/record/RecordingsPanel.java           |   7 +-
 10 files changed, 314 insertions(+), 253 deletions(-)

diff --git 
a/openmeetings-core/src/test/java/org/apache/openmeetings/core/remote/BaseMockedTest.java
 
b/openmeetings-core/src/test/java/org/apache/openmeetings/core/remote/BaseMockedTest.java
index 731a95b..f8f4b6b 100644
--- 
a/openmeetings-core/src/test/java/org/apache/openmeetings/core/remote/BaseMockedTest.java
+++ 
b/openmeetings-core/src/test/java/org/apache/openmeetings/core/remote/BaseMockedTest.java
@@ -23,6 +23,7 @@ import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.when;
+import static org.mockito.MockitoAnnotations.initMocks;
 import static org.powermock.api.mockito.PowerMockito.mockStatic;
 
 import org.apache.openmeetings.core.util.WebSocketHelper;
@@ -35,7 +36,6 @@ import org.kurento.client.internal.TransactionImpl;
 import org.kurento.client.internal.client.RomManager;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
 import org.mockito.Spy;
 import org.powermock.core.classloader.annotations.PrepareForTest;
 import org.powermock.modules.junit4.PowerMockRunner;
@@ -65,7 +65,7 @@ public class BaseMockedTest {
 
        @Before
        public void setup() {
-               MockitoAnnotations.initMocks(this);
+               initMocks(this);
                mockStatic(KurentoClient.class);
                mockStatic(WebSocketHelper.class);
                doReturn(kServerManager).when(client).getServerManager();
diff --git 
a/openmeetings-db/src/test/java/org/apache/openmeetings/db/entity/file/FileItemTest.java
 
b/openmeetings-db/src/test/java/org/apache/openmeetings/db/entity/file/FileItemTest.java
index 562f37e..11e5156 100644
--- 
a/openmeetings-db/src/test/java/org/apache/openmeetings/db/entity/file/FileItemTest.java
+++ 
b/openmeetings-db/src/test/java/org/apache/openmeetings/db/entity/file/FileItemTest.java
@@ -21,6 +21,7 @@ package org.apache.openmeetings.db.entity.file;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.when;
+import static org.mockito.MockitoAnnotations.initMocks;
 import static org.powermock.api.mockito.PowerMockito.mockStatic;
 
 import java.io.File;
@@ -31,7 +32,6 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
 import org.powermock.core.classloader.annotations.PrepareForTest;
 import org.powermock.modules.junit4.PowerMockRunner;
 
@@ -47,7 +47,7 @@ public class FileItemTest {
 
        @Before
        public void setup() {
-               MockitoAnnotations.initMocks(this);
+               initMocks(this);
 
                // Setup path to be local test resources
                mockStatic(OmFileHelper.class);
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
index 2554e84..be17a30 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
@@ -78,6 +78,7 @@ import 
org.apache.openmeetings.web.pages.install.InstallWizardPage;
 import org.apache.openmeetings.web.room.GroupCustomCssResourceReference;
 import org.apache.openmeetings.web.room.RoomPreviewResourceReference;
 import org.apache.openmeetings.web.room.RoomResourceReference;
+import 
org.apache.openmeetings.web.room.sidebar.RoomFileUploadResourceReference;
 import org.apache.openmeetings.web.room.wb.WbWebSocketHelper;
 import org.apache.openmeetings.web.user.dashboard.MyRoomsWidgetDescriptor;
 import org.apache.openmeetings.web.user.dashboard.RecentRoomsWidgetDescriptor;
@@ -321,6 +322,7 @@ public class Application extends 
AuthenticatedWebApplication implements IApplica
                mountResource("/recordings/png/${id}", new 
PngRecordingResourceReference()); //should be in sync with VideoPlayer
                mountResource("/room/file/${id}", new RoomResourceReference());
                mountResource("/room/preview/${id}", new 
RoomPreviewResourceReference());
+               mountResource("/room/file/upload", new 
RoomFileUploadResourceReference());
                mountResource("/profile/${id}", new 
ProfileImageResourceReference());
                mountResource("/group/${id}", new GroupLogoResourceReference());
                mountResource("/group/customcss/${id}", new 
GroupCustomCssResourceReference());
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/OmWebSocketPanel.java
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/OmWebSocketPanel.java
index 3029726..2b758cc 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/OmWebSocketPanel.java
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/OmWebSocketPanel.java
@@ -29,8 +29,7 @@ import org.apache.openmeetings.core.util.WebSocketHelper;
 import org.apache.openmeetings.db.entity.basic.Client;
 import org.apache.openmeetings.db.entity.basic.IWsClient;
 import org.apache.wicket.Component;
-import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
-import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.behavior.Behavior;
 import org.apache.wicket.markup.head.IHeaderResponse;
 import org.apache.wicket.markup.head.JavaScriptHeaderItem;
 import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
@@ -66,7 +65,7 @@ public abstract class OmWebSocketPanel extends Panel {
        @Override
        protected void onInitialize() {
                super.onInitialize();
-               add(newWsBehavior(), new AbstractDefaultAjaxBehavior() {
+               add(newWsBehavior(), new Behavior() {
                        private static final long serialVersionUID = 1L;
 
                        @Override
@@ -75,20 +74,9 @@ public abstract class OmWebSocketPanel extends Panel {
                                        log.debug("pingTimer is attached");
                                        pingable = true;
                                        super.renderHead(component, response);
-                                       
response.render(OnDomReadyHeaderItem.forScript(getJs()));
+                                       
response.render(OnDomReadyHeaderItem.forScript("OmUtil.ping();"));
                                }
                        }
-
-                       private CharSequence getJs() {
-                               return "OmUtil.ping(function(){" + 
getCallbackScript() + "});";
-                       }
-
-                       @Override
-                       protected void respond(AjaxRequestTarget target) {
-                               log.debug("Sending WebSocket PING");
-                               target.appendJavaScript(getJs());
-                               WebSocketHelper.sendClient(getWsClient(), new 
byte[]{getUserId() == null ? 0 : getUserId().byteValue()});
-                       }
                });
        }
 
@@ -137,6 +125,11 @@ public abstract class OmWebSocketPanel extends Panel {
                                                                
WebSocketHelper.sendRoomOthers(c.getRoomId(), c.getUid(), m.put("uid", 
c.getUid()));
                                                        }
                                                                break;
+                                                       case "ping":
+                                                               
log.debug("Sending WebSocket PING");
+                                                               
handler.appendJavaScript("OmUtil.ping();");
+                                                               
WebSocketHelper.sendClient(getWsClient(), new byte[]{getUserId() == null ? 0 : 
getUserId().byteValue()});
+                                                               break;
                                                        default:
                                                                
OmWebSocketPanel.this.onMessage(handler, m);
                                                }
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/main.js 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/main.js
index 08a261f..aa453a7 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/main.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/main.js
@@ -122,8 +122,8 @@ var OmUtil = (function() {
        self.setCssVar = function(key, val) {
                ($('body')[0]).style.setProperty(key, val);
        };
-       self.ping = function(callback) {
-               setTimeout(callback, 30000);
+       self.ping = function() {
+               setTimeout(() => OmUtil.sendMessage({type: 'ping'}), 30000);
        } ;
        return self;
 })();
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomFileUploadResourceReference.java
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomFileUploadResourceReference.java
new file mode 100644
index 0000000..1c9c94a
--- /dev/null
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomFileUploadResourceReference.java
@@ -0,0 +1,218 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License") +  you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openmeetings.web.room.sidebar;
+
+import static 
org.apache.openmeetings.util.OpenmeetingsVariables.getMaxUploadSize;
+import static org.apache.openmeetings.web.app.WebSession.getUserId;
+import static org.apache.openmeetings.web.util.ThreadHelper.startRunnable;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.DoubleConsumer;
+
+import javax.ws.rs.core.MediaType;
+
+import org.apache.commons.fileupload.FileItem;
+import org.apache.openmeetings.core.data.file.FileProcessor;
+import org.apache.openmeetings.core.util.WebSocketHelper;
+import org.apache.openmeetings.db.dao.file.FileItemDao;
+import org.apache.openmeetings.db.dao.file.FileItemLogDao;
+import org.apache.openmeetings.db.entity.basic.Client;
+import org.apache.openmeetings.db.entity.file.BaseFileItem;
+import org.apache.openmeetings.db.entity.room.Room;
+import org.apache.openmeetings.db.entity.room.Room.Right;
+import org.apache.openmeetings.db.entity.room.Room.RoomElement;
+import org.apache.openmeetings.util.process.ProcessResult;
+import org.apache.openmeetings.util.process.ProcessResultList;
+import org.apache.openmeetings.web.app.Application;
+import org.apache.openmeetings.web.app.ClientManager;
+import org.apache.wicket.injection.Injector;
+import org.apache.wicket.protocol.http.servlet.MultipartServletWebRequest;
+import org.apache.wicket.protocol.http.servlet.ServletWebRequest;
+import org.apache.wicket.request.resource.AbstractResource;
+import org.apache.wicket.request.resource.AbstractResource.ResourceResponse;
+import org.apache.wicket.request.resource.AbstractResource.WriteCallback;
+import org.apache.wicket.request.resource.IResource;
+import org.apache.wicket.request.resource.IResource.Attributes;
+import org.apache.wicket.request.resource.ResourceReference;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+import org.apache.wicket.util.lang.Bytes;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.github.openjson.JSONObject;
+
+public class RoomFileUploadResourceReference extends ResourceReference {
+       private static final long serialVersionUID = 1L;
+       private static final Logger log = 
LoggerFactory.getLogger(RoomFileUploadResourceReference.class);
+       private static final String PARAM_FILE_NAME = "room-upload-file";
+       private static final String PARAM_TO_WB_NAME = "room-upload-to-wb";
+       private static final String PARAM_CLEAN_NAME = "room-upload-clean";
+       private static final String PARAM_SID_NAME = "room-upload-sid";
+       private static final String PARAM_LAST_SELECTED_NAME = 
"room-upload-last-selected";
+       private static enum Status {
+               SUCCESS
+               , PROGRESS
+               , ERROR
+       }
+
+       @SpringBean
+       private ClientManager cm;
+       @SpringBean
+       private FileProcessor processor;
+       @SpringBean
+       private FileItemLogDao fileLogDao;
+       @SpringBean
+       private FileItemDao fileDao;
+
+       public RoomFileUploadResourceReference() {
+               super(RoomFileUploadResourceReference.class, 
"room-file-upload");
+               Injector.get().inject(this);
+       }
+
+       @Override
+       public IResource getResource() {
+               return new AbstractResource() {
+                       private static final long serialVersionUID = 1L;
+
+                       @Override
+                       protected ResourceResponse 
newResourceResponse(Attributes attributes) {
+                               final ResourceResponse response = new 
ResourceResponse();
+                               final ServletWebRequest webRequest = 
(ServletWebRequest) attributes.getRequest();
+                               try {
+                                       MultipartServletWebRequest 
multiPartRequest = 
webRequest.newMultipartWebRequest(Bytes.bytes(getMaxUploadSize()), "ignored");
+                                       multiPartRequest.parseFileParts();
+
+                                       String sid = 
multiPartRequest.getPostParameters().getParameterValue(PARAM_SID_NAME).toString();
+                                       Client c = cm.getBySid(sid);
+                                       final long langId = getLangId(c);
+                                       if (isUploadAllowed(c)) {
+                                               Map<String, List<FileItem>> 
files = multiPartRequest.getFiles();
+                                               final List<FileItem> fileItems 
= files.get(PARAM_FILE_NAME);
+
+                                               final boolean toWb = 
multiPartRequest.getPostParameters().getParameterValue(PARAM_TO_WB_NAME).toBoolean(false);
+                                               final boolean clean = 
multiPartRequest.getPostParameters().getParameterValue(PARAM_CLEAN_NAME).toBoolean(false);
+                                               final long lastSelected = 
multiPartRequest.getPostParameters().getParameterValue(PARAM_LAST_SELECTED_NAME).toLong(-1L);
+                                               startRunnable(() -> 
convertAll(c, fileItems, toWb, clean, lastSelected));
+
+                                               prepareResponse(response, 
Status.SUCCESS, Application.getString("54", langId));
+                                       } else {
+                                               prepareResponse(response, 
Status.ERROR, Application.getString("access.denied.header", langId));
+                                       }
+                               } catch (Exception e) {
+                                       log.error("An error occurred while 
uploading a file", e);
+                                       prepareResponse(response, Status.ERROR, 
e.getMessage());
+                               }
+                               return response;
+                       }
+               };
+       }
+
+       private static long getLangId(Client c) {
+               return c == null || c.getUser() == null ? 1L : 
c.getUser().getLanguageId();
+       }
+
+       private static void prepareResponse(ResourceResponse response, Status 
status, String msg) {
+               response.setContentType(MediaType.APPLICATION_JSON);
+               response.setWriteCallback(new WriteCallback() {
+                       @Override
+                       public void writeData(Attributes attributes) throws 
IOException {
+                               attributes.getResponse().write(new JSONObject()
+                                               .put("status", status.name())
+                                               .put("message", msg)
+                                               .toString());
+                       }
+               });
+       }
+
+       private static boolean isUploadAllowed(Client c) {
+               if (c == null || c.getRoom() == null || Room.Type.INTERVIEW == 
c.getRoom().getType()) {
+                       return false;
+               }
+               Room r = c.getRoom();
+               return !r.isHidden(RoomElement.FILES) && 
c.hasRight(Right.PRESENTER);
+       }
+
+       private void convertAll(Client c, List<FileItem> files, boolean toWb, 
boolean clean, long lastSelected) {
+               final BaseFileItem parent = fileDao.get(lastSelected);
+               final long langId = getLangId(c);
+               final long totalSize = 
files.stream().mapToLong(FileItem::getSize).sum();
+               final AtomicInteger progress = new AtomicInteger(0);
+               long currentSize = 0;
+               for (FileItem curItem : files) {
+                       long size = curItem.getSize();
+                       try {
+                               org.apache.openmeetings.db.entity.file.FileItem 
f = new org.apache.openmeetings.db.entity.file.FileItem();
+                               f.setSize(size);
+                               f.setName(curItem.getName());
+                               if (parent == null || 
BaseFileItem.Type.RECORDING == parent.getType()) {
+                                       f.setOwnerId(getUserId());
+                               } else {
+                                       f.setRoomId(parent.getRoomId());
+                                       f.setOwnerId(parent.getOwnerId());
+                                       f.setGroupId(parent.getGroupId());
+                                       if (parent.getId() != null) {
+                                               
f.setParentId(BaseFileItem.Type.FOLDER == parent.getType() ? parent.getId() : 
parent.getParentId());
+                                       }
+                               }
+                               f.setInsertedBy(getUserId());
+
+                               ProcessResultList logs = 
processor.processFile(f, curItem.getInputStream()
+                                               , 
Optional.<DoubleConsumer>of(part -> sendProgress(c, progress, progress.get() + 
(int)(100 * part * size / totalSize))));
+                               for (ProcessResult res : logs.getJobs()) {
+                                       fileLogDao.add(res.getProcess(), f, 
res);
+                               }
+                               if (logs.hasError()) {
+                                       sendError(c, 
Application.getString("convert.errors.file", langId));
+                               } else {
+                                       if (toWb) {
+                                               //FIXME TODO 
room.getWb().sendFileToWb(f, clean);
+                                               clean = false;
+                                       }
+                               }
+                       } catch (Exception e) {
+                               log.error("Unexpected error while processing 
uploaded file", e);
+                               sendError(c, e.getMessage() == null ? 
"Unexpected error" : e.getMessage());
+                       } finally {
+                               curItem.delete();
+                       }
+                       currentSize += size;
+                       sendProgress(c, progress, (int)(100 * currentSize / 
totalSize));
+               }
+               sendProgress(c, progress, 100);
+       }
+
+       private void sendError(Client c, String msg) {
+               WebSocketHelper.sendClient(c, new JSONObject()
+                               .put("status", Status.ERROR.name())
+                               .put("message", msg));
+       }
+
+       private void sendProgress(Client c, AtomicInteger progress, int cur) {
+               if (cur > progress.get()) {
+                       progress.set(cur);
+                       WebSocketHelper.sendClient(c, new JSONObject()
+                                       .put("status", Status.PROGRESS.name())
+                                       .put("progress", cur));
+               }
+       }
+}
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/UploadDialog.html
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/UploadDialog.html
index 181cf1d..81c9a4e 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/UploadDialog.html
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/UploadDialog.html
@@ -21,26 +21,25 @@
 <!DOCTYPE html>
 <html xmlns:wicket="http://wicket.apache.org";>
 <wicket:extend>
-       <form wicket:id="form">
+       <form wicket:id="form" id="room-upload-form" method="post" 
enctype="multipart/form-data">
                <div class="mb-4"><wicket:message key="594"/></div>
                <div class="fileinput fileinput-new d-inline m-0" 
data-provides="fileinput">
                        <div class="fileinput-filename d-block"></div>
                        <span class="btn btn-file btn-outline-primary">
                                <span><wicket:message key="596"/></span>
-                               <input type="file" multiple="multiple" 
wicket:id="file"/>
+                               <input type="file" multiple="multiple" 
id="room-upload-file" name="room-upload-file"/>
                        </span>
                </div>
-               <div wicket:id="feedback" class="error"></div>
+               <div class="error"></div>
                <div class="mt-3">
-                       <input wicket:id="to-wb" type="checkbox"/><label 
wicket:for="to-wb"><wicket:message key="1312"/></label>
-                       <div class="ml-3" wicket:id="clean-block">
-                               <input wicket:id="clean-wb" 
type="checkbox"/><label wicket:for="clean-wb"><wicket:message key="62"/></label>
+                       <input id="room-upload-to-wb" name="room-upload-to-wb" 
type="checkbox" value="true"/>&nbsp;<label 
for="room-upload-to-wb"><wicket:message key="1312"/></label>
+                       <div class="ml-3 d-none" id="room-upload-clean-block">
+                               <input id="room-upload-clean" 
name="room-upload-clean" type="checkbox" value="true"/>&nbsp;<label 
for="room-upload-clean"><wicket:message key="62"/></label>
                        </div>
                </div>
+               <input wicket:id="sid" name="room-upload-sid" type="hidden"/>
+               <input wicket:id="lastSelected" 
name="room-upload-last-selected" type="hidden" value=""/>
        </form>
-       <div wicket:id="progress"></div>
-       <form wicket:id="name-form">
-               <input type="hidden" wicket:id="name"/>
-       </form>
+       <div id="progress"></div>
 </wicket:extend>
 </html>
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/UploadDialog.java
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/UploadDialog.java
index 81c57a8..1651cc8 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/UploadDialog.java
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/UploadDialog.java
@@ -19,133 +19,42 @@
 package org.apache.openmeetings.web.room.sidebar;
 
 import static 
org.apache.openmeetings.util.OpenmeetingsVariables.getMaxUploadSize;
-import static org.apache.openmeetings.web.app.WebSession.getUserId;
-
-import java.time.Duration;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-import java.util.function.DoubleConsumer;
 
 import org.apache.openmeetings.core.data.file.FileProcessor;
 import org.apache.openmeetings.db.dao.file.FileItemLogDao;
-import org.apache.openmeetings.db.entity.file.BaseFileItem;
-import org.apache.openmeetings.db.entity.file.FileItem;
-import org.apache.openmeetings.util.process.ProcessResult;
-import org.apache.openmeetings.util.process.ProcessResultList;
+import org.apache.openmeetings.web.app.WebSession;
 import org.apache.openmeetings.web.common.OmModalCloseButton;
 import org.apache.openmeetings.web.room.RoomPanel;
-import org.apache.openmeetings.web.util.ThreadHelper;
 import org.apache.openmeetings.web.util.upload.BootstrapFileUploadBehavior;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.ajax.form.AjaxFormSubmitBehavior;
-import org.apache.wicket.ajax.form.OnChangeAjaxBehavior;
+import org.apache.wicket.behavior.AttributeAppender;
 import org.apache.wicket.core.request.handler.IPartialPageRequestHandler;
 import org.apache.wicket.markup.head.IHeaderResponse;
 import org.apache.wicket.markup.head.JavaScriptHeaderItem;
 import org.apache.wicket.markup.head.PriorityHeaderItem;
 import org.apache.wicket.markup.html.WebMarkupContainer;
-import org.apache.wicket.markup.html.form.CheckBox;
-import org.apache.wicket.markup.html.form.Form;
-import org.apache.wicket.markup.html.form.HiddenField;
-import org.apache.wicket.markup.html.form.upload.FileUpload;
-import org.apache.wicket.markup.html.form.upload.FileUploadField;
-import org.apache.wicket.model.IModel;
-import org.apache.wicket.model.Model;
 import org.apache.wicket.model.ResourceModel;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
 import org.apache.wicket.request.resource.JavaScriptResourceReference;
 import org.apache.wicket.spring.injection.annot.SpringBean;
 import org.apache.wicket.util.lang.Bytes;
-import org.apache.wicket.util.string.Strings;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import de.agilecoders.wicket.core.markup.html.bootstrap.button.Buttons;
-import 
de.agilecoders.wicket.core.markup.html.bootstrap.common.NotificationPanel;
-import 
de.agilecoders.wicket.core.markup.html.bootstrap.components.progress.UpdatableProgressBar;
 import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
-import 
de.agilecoders.wicket.core.markup.html.bootstrap.utilities.BackgroundColorBehavior;
-import 
de.agilecoders.wicket.extensions.markup.html.bootstrap.spinner.SpinnerAjaxButton;
 
 public class UploadDialog extends Modal<String> {
        private static final long serialVersionUID = 1L;
        private static final Logger log = 
LoggerFactory.getLogger(UploadDialog.class);
-       private final NotificationPanel feedback = new 
NotificationPanel("feedback");
-       private final Form<String> form = new Form<>("form") {
-               private static final long serialVersionUID = 1L;
-
-               @Override
-               protected boolean handleMultiPart() {
-                       try {
-                               return super.handleMultiPart();
-                       } catch (Exception e) {
-                               log.warn("Multipart processing failed {}", 
e.getMessage());
-                       }
-                       return true;
-               }
-       };
-       private SpinnerAjaxButton upload;
-       private final FileUploadField uploadField = new FileUploadField("file", 
new IModel<List<FileUpload>>() {
-               private static final long serialVersionUID = 1L;
-
-               @Override
-               public void setObject(List<FileUpload> object) {
-                       //no-op
-               }
-
-               @Override
-               public List<FileUpload> getObject() {
-                       return new ArrayList<>();
-               }
-       }) {
-               private static final long serialVersionUID = 1L;
-
-               @Override
-               protected boolean forceCloseStreamsOnDetach() {
-                       return false;
-               }
-       };
-       private final HiddenField<String> fileName = new HiddenField<>("name", 
Model.of(""));
-       private final CheckBox toWb = new CheckBox("to-wb", Model.of(false));
-       private final WebMarkupContainer cleanBlock = new 
WebMarkupContainer("clean-block");
-       private final CheckBox cleanWb = new CheckBox("clean-wb", 
Model.of(false));
+       private final WebMarkupContainer form = new WebMarkupContainer("form");
        private final RoomFilePanel roomFiles;
        private final RoomPanel room;
+       private final WebMarkupContainer lastSelected = new 
WebMarkupContainer("lastSelected");
 
        @SpringBean
        private FileProcessor processor;
        @SpringBean
        private FileItemLogDao fileLogDao;
 
-       private final UpdatableProgressBar progressBar = new 
UpdatableProgressBar("progress", new Model<>(0), 
BackgroundColorBehavior.Color.Info, true) {
-               private static final long serialVersionUID = 1L;
-
-               @Override
-               protected IModel<Integer> newValue() {
-                       return Model.of(progress);
-               }
-
-               @Override
-               protected void onPostProcessTarget(IPartialPageRequestHandler 
target) {
-                       super.onPostProcessTarget(target);
-                       
target.appendJavaScript("Ladda.create(document.getElementById('" + 
upload.getMarkupId() + "')).start()");
-               }
-
-               @Override
-               protected void onComplete(IPartialPageRequestHandler target) {
-                       progressBar.setVisible(false);
-                       room.getSidebar().updateFiles(target);
-                       if (form.hasError()) {
-                               target.add(form.setVisible(true));
-                               target.add(feedback);
-                       } else {
-                               close(target);
-                       }
-                       target.add(progressBar);
-               }
-       };
-       private int progress = 0;
-
        public UploadDialog(String id, RoomPanel room, RoomFilePanel roomFiles) 
{
                super(id);
                this.roomFiles = roomFiles;
@@ -158,73 +67,26 @@ public class UploadDialog extends Modal<String> {
                setCloseOnEscapeKey(false);
                setBackdrop(Backdrop.STATIC);
 
-               
add(form.setOutputMarkupId(true).setOutputMarkupPlaceholderTag(true));
-               toWb.add(new OnChangeAjaxBehavior() {
-                       private static final long serialVersionUID = 1L;
-
-                       @Override
-                       protected void onUpdate(AjaxRequestTarget target) {
-                               
target.add(cleanBlock.setVisible(toWb.getModelObject()));
-                       }
-               });
-               form.add(feedback.setOutputMarkupId(true), 
toWb.setOutputMarkupId(true)
-                               , 
cleanBlock.add(cleanWb.setOutputMarkupId(true)).setVisible(false).setOutputMarkupPlaceholderTag(true));
-
-               form.setMultiPart(true);
-               form.setMaxSize(Bytes.bytes(getMaxUploadSize()));
-               // Model is necessary here to avoid writing image to the User 
object
-               form.add(uploadField);
-               final Form<String> nameForm = new Form<>("name-form");
-               fileName.add(new AjaxFormSubmitBehavior(nameForm, "change") {
-                       private static final long serialVersionUID = 1L;
-
-                       @Override
-                       protected void onSubmit(AjaxRequestTarget target) {
-                               if 
(!Strings.isEmpty(getComponent().getDefaultModelObjectAsString())) {
-                                       target.add(upload.setEnabled(true));
-                               }
-                       }
-               }).setOutputMarkupId(true);
-
-               add(nameForm.add(fileName.setOutputMarkupId(true)));
+               add(form.add(AttributeAppender.append("data-max-size", 
getMaxUploadSize()))
+                               
.add(AttributeAppender.append("data-max-size-lbl", 
Bytes.bytes(getMaxUploadSize()).toString(WebSession.get().getLocale())))
+                               
.add(AttributeAppender.append("data-upload-lbl", getString("593")))
+                               
.add(AttributeAppender.append("data-max-upload-lbl", getString("1491")))
+                               .add(AttributeAppender.append("action", "" + 
urlFor(new RoomFileUploadResourceReference(), new PageParameters())))
+                               .setOutputMarkupId(true)
+                               .setOutputMarkupPlaceholderTag(true));
+               form.add(new 
WebMarkupContainer("sid").add(AttributeAppender.append("value", 
room.getClient().getSid())).setMarkupId("room-upload-sid").setOutputMarkupId(true));
+               
form.add(lastSelected.setMarkupId("room-upload-last-selected").setOutputMarkupId(true));
                add(BootstrapFileUploadBehavior.INSTANCE);
-               addButton(upload = new SpinnerAjaxButton("button", new 
ResourceModel("593"), form, Buttons.Type.Outline_Primary) {
-                       private static final long serialVersionUID = 1L;
-
-                       @Override
-                       protected void onError(AjaxRequestTarget target) {
-                               target.add(feedback);
-                       }
-
-                       @Override
-                       protected void onSubmit(AjaxRequestTarget target) {
-                               List<FileUpload> ful = 
uploadField.getFileUploads();
-                               if (ful != null) {
-
-                                       progress = 0;
-                                       progressBar.restart(target);
-                                       target.add(
-                                                       
progressBar.setModelObject(progress).setVisible(true)
-                                                       , 
form.setVisible(false));
-
-                                       
ThreadHelper.startRunnable(UploadDialog.this::convertAll);
-                               }
-                       }
-               });
-               upload.setEnabled(false);
                addButton(OmModalCloseButton.of("85"));
 
-               
progressBar.updateInterval(Duration.ofSeconds(1)).stop(null).striped(false);
-               
add(progressBar.setOutputMarkupPlaceholderTag(true).setVisible(false));
                super.onInitialize();
        }
 
        @Override
        public Modal<String> show(IPartialPageRequestHandler handler) {
-               handler.add(upload.setEnabled(true));
-               uploadField.setModelObject(new ArrayList<>());
-               handler.add(form.setVisible(true), fileName);
-               handler.appendJavaScript(String.format("bindUpload('%s', 
'%s');", form.getMarkupId(), fileName.getMarkupId()));
+               lastSelected.add(AttributeAppender.replace("value", 
roomFiles.getLastSelected().getId()));
+               handler.add(form.setVisible(true));
+               handler.appendJavaScript(String.format("bindUpload();"));
                return super.show(handler);
        }
 
@@ -233,54 +95,4 @@ public class UploadDialog extends Modal<String> {
                super.renderHead(response);
                response.render(new 
PriorityHeaderItem(JavaScriptHeaderItem.forReference(new 
JavaScriptResourceReference(UploadDialog.class, "upload.js"))));
        }
-
-       private void convertAll() {
-               List<FileUpload> ful = uploadField.getFileUploads();
-               final BaseFileItem parent = roomFiles.getLastSelected();
-               boolean clean = cleanWb.getModelObject();
-               final long totalSize = 
ful.stream().mapToLong(FileUpload::getSize).sum();
-               long currentSize = 0;
-               for (FileUpload fu : ful) {
-                       long size = fu.getSize();
-                       try {
-                               FileItem f = new FileItem();
-                               f.setSize(size);
-                               f.setName(fu.getClientFileName());
-                               if (parent == null || !(parent instanceof 
FileItem)) {
-                                       f.setOwnerId(getUserId());
-                               } else {
-                                       f.setRoomId(parent.getRoomId());
-                                       f.setOwnerId(parent.getOwnerId());
-                                       f.setGroupId(parent.getGroupId());
-                                       if (parent.getId() != null) {
-                                               
f.setParentId(BaseFileItem.Type.FOLDER == parent.getType() ? parent.getId() : 
parent.getParentId());
-                                       }
-                               }
-                               f.setInsertedBy(getUserId());
-
-                               ProcessResultList logs = 
processor.processFile(f, fu.getInputStream()
-                                               , 
Optional.<DoubleConsumer>of(part -> progress += (int)(100 * part * size / 
totalSize)));
-                               for (ProcessResult res : logs.getJobs()) {
-                                       fileLogDao.add(res.getProcess(), f, 
res);
-                               }
-                               if (logs.hasError()) {
-                                       
form.error(getString("convert.errors.file"));
-                               } else {
-                                       if (toWb.getModelObject()) {
-                                               room.getWb().sendFileToWb(f, 
clean);
-                                               clean = false;
-                                       }
-                               }
-                       } catch (Exception e) {
-                               log.error("Unexpected error while processing 
uploaded file", e);
-                               form.error(e.getMessage() == null ? "Unexpected 
error" : e.getMessage());
-                       } finally {
-                               fu.closeStreams();
-                               fu.delete();
-                       }
-                       currentSize += size;
-                       progress = (int)(100 * currentSize / totalSize);
-               }
-               progress = 100;
-       }
 }
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/upload.js
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/upload.js
index df0d0a8..0791978 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/upload.js
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/upload.js
@@ -1,21 +1,63 @@
 /* Licensed under the Apache License, Version 2.0 (the "License") 
http://www.apache.org/licenses/LICENSE-2.0 */
-function bindUpload(markupId, hiddenId) {
-       const fi = $('#' + markupId + ' .fileinput');
+function bindUpload() {
+       const form = $('#room-upload-form')
+                       , fi = form.find('.fileinput')
+       let uploadBtn = $('#room-upload-btn');
+       if (uploadBtn.length === 0) {
+               uploadBtn = $('<button id="room-upload-btn" class="btn 
btn-outline-primary"></button>')
+                       .text(form.data('upload-lbl'));
+               
form.parents('.modal-content').find('.modal-footer').prepend(uploadBtn);
+               uploadBtn.click(function() {
+                       $.ajax({
+                               url: form.attr('action')
+                               , type: 'POST'
+                               , data: new FormData($('#room-upload-form')[0])
+                               , processData: false
+                               , contentType: false
+                       }).done(function(data) {
+                               let i = 0;
+                       }).fail(function(e) {
+                               let i = 0;
+                       });
+               });
+       }
+       uploadBtn.attr('disabled', 'disabled');
        if (!fi.eventAdded) {
-               $('#' + markupId + ' .fileinput').on('change.bs.fileinput', 
function(event) {
+               fi.on('change.bs.fileinput', function(event) {
                        event.stopPropagation();
-                       const th = $(this),
-                       fInput = th.find('input[type=file]'),
-                       fn = th.find('.fileinput-filename');
-                       if (fInput[0].files !== undefined && 
fInput[0].files.length > 1) {
-                               fn.text($.map(fInput[0].files, function(val) { 
return val.name; }).join(', '));
+                       const th = $(this)
+                               , fInput = th.find('input[type=file]')
+                               , fn = th.find('.fileinput-filename')
+                               , files = fInput[0].files
+                               , errors = form.find('.error');
+                       errors.html('');
+                       let     valid = files !== undefined && files.length > 0;
+                       if (valid) {
+                               const size = Array.from(files).map(f => 
f.size).reduce((a, b) => a + b, 0);
+                               valid = size < +form.data('max-size');
+                               if (!valid) {
+                                       errors.html($('<div class="alert 
alert-danger" role="alert"></div>').text(form.data('max-upload-lbl') + ' ' + 
form.data('max-size-lbl')));
+                               }
+                       }
+                       if (valid) {
+                               fn.text(Array.from(files).map(f => 
f.name).join(', '));
+                               uploadBtn.removeAttr('disabled');
+                       } else {
+                               fn.text('');
+                               uploadBtn.attr('disabled', 'disabled');
+                               $('#room-upload-file').val('');
                        }
                        fInput.attr('title', fn.text());
-                       const hi = $('#' + hiddenId);
-                       hi.val(fn.text());
-                       hi.trigger('change');
                        return false;
                });
+               $('#room-upload-to-wb').click(function() {
+                       const clnBlock = $('#room-upload-clean-block');
+                       if ($(this).prop('checked')) {
+                               clnBlock.removeClass('d-none');
+                       } else {
+                               clnBlock.addClass('d-none');
+                       }
+               });
                fi.eventAdded = true;
        }
 }
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/RecordingsPanel.java
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/RecordingsPanel.java
index 6c80fa9..aec9bb7 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/RecordingsPanel.java
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/RecordingsPanel.java
@@ -127,12 +127,7 @@ public class RecordingsPanel extends UserBasePanel {
                                        @Override
                                        public void onClick(AjaxRequestTarget 
target) {
                                                final IRecordingConverter 
converter = isInterview ? interviewConverter : recordingConverter;
-                                               new Thread() {
-                                                       @Override
-                                                       public void run() {
-                                                               
converter.startConversion((Recording)getLastSelected());
-                                                       }
-                                               }.start();
+                                               new Thread(() -> 
converter.startConversion((Recording)getLastSelected())).start();
                                        }
                                }, new BootstrapAjaxLink<>(markupId, 
Model.of(""), Buttons.Type.Outline_Success, new 
ResourceModel("button.label.share")) {
                                        private static final long 
serialVersionUID = 1L;

Reply via email to