This is an automated email from the ASF dual-hosted git repository. solomax pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/openmeetings.git
The following commit(s) were added to refs/heads/master by this push: new e6465e7 [OPENMEETINGS-2217] recordings are downloadable for room e6465e7 is described below commit e6465e74cef1694194b59360cfed9e69baf9130e Author: Maxim Solodovnik <solomax...@gmail.com> AuthorDate: Sun May 24 20:26:59 2020 +0700 [OPENMEETINGS-2217] recordings are downloadable for room --- .../core/util/StrongPasswordValidator.java | 3 +- .../web/common/tree/FileTreePanel.html | 7 +- .../web/common/tree/FileTreePanel.java | 167 +++++++++++++-------- .../apache/openmeetings/web/pages/HashPage.java | 2 +- .../web/user/record/RecordingsPanel.html | 1 + .../web/user/record/RecordingsPanel.java | 90 +++++++++++ .../openmeetings/web/user/record/VideoInfo.html | 4 - .../openmeetings/web/user/record/VideoInfo.java | 130 +--------------- openmeetings-web/src/main/webapp/css/raw-tree.css | 4 + .../src/main/webapp/css/raw-variables.css | 4 +- .../webservice/AbstractWebServiceTest.java | 2 +- 11 files changed, 210 insertions(+), 204 deletions(-) diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/StrongPasswordValidator.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/StrongPasswordValidator.java index ec40471..de03860 100644 --- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/StrongPasswordValidator.java +++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/StrongPasswordValidator.java @@ -25,7 +25,6 @@ import java.util.Map; import org.apache.openmeetings.db.dao.label.LabelDao; import org.apache.openmeetings.db.entity.user.User; -import org.apache.wicket.util.collections.MicroMap; import org.apache.wicket.util.string.Strings; import org.apache.wicket.validation.IValidatable; import org.apache.wicket.validation.IValidator; @@ -124,7 +123,7 @@ public class StrongPasswordValidator implements IValidator<String> { @Override public void validate(IValidatable<String> pass) { if (badLength(pass.getValue())) { - error(pass, "bad.password.short", new MicroMap<String, Object>("0", getMinPasswdLength())); + error(pass, "bad.password.short", Map.of("0", getMinPasswdLength())); } if (noLowerCase(pass.getValue())) { error(pass, "bad.password.lower"); diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.html index 6d787f0..99ef290 100644 --- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.html +++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.html @@ -52,12 +52,17 @@ <div wicket:id="tree"></div> </div> <div class="footer"> - <span wicket:id="download" wicket:message="title:867"></span> <div wicket:id="sizes" class="sizes"> <span class="size" wicket:message="title:923" wicket:id="homeSize"></span> <span class="size">/</span> <span class="size" wicket:message="title:924" wicket:id="publicSize"></span> </div> + <div class="buttons" wicket:id="buttons"> + <span wicket:id="download" wicket:message="title:867"></span> + <div wicket:id="other-buttons" class="other-buttons"> + <button wicket:id="button"></button> + </div> + </div> </div> <div wicket:id="errors"></div> </div> diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.java index 1082227..1d96d1e 100644 --- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.java +++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.java @@ -21,8 +21,10 @@ package org.apache.openmeetings.web.common.tree; import static java.time.Duration.ZERO; import static java.util.UUID.randomUUID; import static org.apache.openmeetings.util.OmFileHelper.EXTENSION_JPG; +import static org.apache.openmeetings.util.OmFileHelper.EXTENSION_MP4; import static org.apache.openmeetings.util.OmFileHelper.EXTENSION_PDF; import static org.apache.openmeetings.util.OpenmeetingsVariables.ATTR_CLASS; +import static org.apache.openmeetings.util.OpenmeetingsVariables.ATTR_TITLE; import static org.apache.openmeetings.web.app.WebSession.getUserId; import static org.apache.openmeetings.web.common.BasePanel.EVT_CLICK; import static org.apache.openmeetings.web.pages.BasePage.ALIGN_LEFT; @@ -57,6 +59,8 @@ import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.link.AbstractLink; +import org.apache.wicket.markup.html.list.ListItem; +import org.apache.wicket.markup.html.list.ListView; import org.apache.wicket.markup.html.panel.Panel; import org.apache.wicket.model.IModel; import org.apache.wicket.model.Model; @@ -73,6 +77,7 @@ import com.googlecode.wicket.jquery.core.ajax.JQueryAjaxBehavior; import com.googlecode.wicket.jquery.ui.interaction.droppable.Droppable; import com.googlecode.wicket.jquery.ui.interaction.droppable.DroppableBehavior; +import de.agilecoders.wicket.core.markup.html.bootstrap.behavior.CssClassNameAppender; import de.agilecoders.wicket.core.markup.html.bootstrap.button.BootstrapAjaxLink; import de.agilecoders.wicket.core.markup.html.bootstrap.button.ButtonBehavior; import de.agilecoders.wicket.core.markup.html.bootstrap.button.Buttons; @@ -112,60 +117,8 @@ public abstract class FileTreePanel extends Panel { protected final IModel<String> homeSize = Model.of((String)null); protected final IModel<String> publicSize = Model.of((String)null); final ConvertingErrorsDialog errorsDialog = new ConvertingErrorsDialog("errors", Model.of((Recording)null)); - final FileItemTree tree; - private final SplitButton download = new SplitButton("download", Model.of("")) { - private static final long serialVersionUID = 1L; - - private AbstractLink createLink(String markupId, IModel<String> model, String ext) { - return new BootstrapAjaxLink<>(markupId, model, Buttons.Type.Outline_Primary, model) { - private static final long serialVersionUID = 1L; - - @Override - public boolean isEnabled() { - File f = null; - if (getSelected().size() == 1) { - f = getLastSelected().getFile(ext); - } - return f != null && f.exists(); - } - - @Override - public void onClick(AjaxRequestTarget target) { - onDownlownClick(target, ext); - } - }.setIconType(FontAwesome5IconType.download_s); - } - - @Override - protected List<AbstractLink> newSubMenuButtons(String buttonMarkupId) { - return List.of( - createLink(buttonMarkupId, new ResourceModel("files.download.original"), null) - , createLink(buttonMarkupId, new ResourceModel("files.download.pdf"), EXTENSION_PDF) - , createLink(buttonMarkupId, new ResourceModel("files.download.jpg"), EXTENSION_JPG) - ); - } - - @Override - protected void addButtonBehavior(ButtonBehavior buttonBehavior) { - buttonBehavior.setSize(Buttons.Size.Small).setType(Buttons.Type.Outline_Secondary); - super.addButtonBehavior(buttonBehavior); - } - - @Override - protected AbstractLink newBaseButton(String markupId, IModel<String> labelModel, IModel<IconType> iconTypeModel) { - return createLink(markupId, new ResourceModel("files.download.original"), null); - } - - public void onDownlownClick(AjaxRequestTarget target, String ext) { - BaseFileItem fi = getLastSelected(); - File f = ext == null && (Type.IMAGE == fi.getType() || Type.PRESENTATION == fi.getType()) - ? fi.getOriginal() : fi.getFile(ext); - if (f != null && f.exists()) { - dwnldFile = f; - downloader.initiate(target); - } - } - }; + FileItemTree tree; + private final WebMarkupContainer buttons = new WebMarkupContainer("buttons"); private final Form<Void> form = new Form<>("form"); private final NameDialog addFolder; private ConfirmableAjaxBorder trashBorder; @@ -180,6 +133,7 @@ public abstract class FileTreePanel extends Panel { } }); private final Component upload = new WebMarkupContainer("upload"); + @SpringBean private RecordingDao recDao; @SpringBean @@ -189,16 +143,15 @@ public abstract class FileTreePanel extends Panel { super(id); this.roomId = roomId; this.addFolder = addFolder; - final OmTreeProvider tp = new OmTreeProvider(roomId); - select(tp.getRoot(), null, false, false); - form.add(tree = new FileItemTree("tree", this, tp)); - form.add(download.setVisible(false).setOutputMarkupPlaceholderTag(true)); - add(form.add(downloader)); } @Override protected void onInitialize() { super.onInitialize(); + final OmTreeProvider tp = new OmTreeProvider(roomId); + select(tp.getRoot(), null, false, false); + form.add(tree = new FileItemTree("tree", this, tp)); + add(form.add(downloader)); Droppable<BaseFileItem> trashToolbar = new Droppable<>("trash-toolbar") { private static final long serialVersionUID = 1L; @@ -261,6 +214,92 @@ public abstract class FileTreePanel extends Panel { form.add(sizes.add(new Label("homeSize", homeSize), new Label("publicSize", publicSize)).setOutputMarkupId(true)); form.add(errorsDialog); setReadOnly(false, null); + final SplitButton download = new SplitButton("download", Model.of("")) { + private static final long serialVersionUID = 1L; + + private boolean isDownloadable(BaseFileItem f) { + return !f.isReadOnly() && (Type.PRESENTATION == f.getType() || Type.IMAGE == f.getType() || Type.RECORDING == f.getType()); + } + + private AbstractLink createLink(String markupId, IModel<String> model, String ext) { + return new BootstrapAjaxLink<>(markupId, model, Buttons.Type.Outline_Primary, model) { + private static final long serialVersionUID = 1L; + + @Override + protected void onConfigure() { + super.onConfigure(); + for (CssClassNameAppender b : getBehaviors(CssClassNameAppender.class)) { + remove(b); + } + File f = null; + if (getSelected().size() == 1) { + BaseFileItem fi = getLastSelected(); + if (isDownloadable(fi)) { + f = fi.getFile(ext); + } + } + setEnabled(f != null && f.exists()); + } + + @Override + public void onClick(AjaxRequestTarget target) { + onDownlownClick(target, ext); + } + }.setIconType(FontAwesome5IconType.download_s); + } + + @Override + protected List<AbstractLink> newSubMenuButtons(String buttonMarkupId) { + return List.of( + createLink(buttonMarkupId, new ResourceModel("files.download.original"), null) + , createLink(buttonMarkupId, new ResourceModel("files.download.pdf"), EXTENSION_PDF) + , createLink(buttonMarkupId, new ResourceModel("files.download.jpg"), EXTENSION_JPG) + , createLink(buttonMarkupId, Model.of(EXTENSION_MP4), EXTENSION_MP4) + ); + } + + @Override + protected void addButtonBehavior(ButtonBehavior buttonBehavior) { + buttonBehavior.setSize(Buttons.Size.Small).setType(Buttons.Type.Outline_Secondary); + super.addButtonBehavior(buttonBehavior); + } + + @Override + protected AbstractLink newBaseButton(String markupId, IModel<String> labelModel, IModel<IconType> iconTypeModel) { + AbstractLink btn = createLink(markupId, Model.of(""), null); + btn.add(AttributeModifier.append(ATTR_TITLE, new ResourceModel("867"))); + return btn; + } + + @Override + protected void onConfigure() { + super.onConfigure(); + boolean enabled = false; + if (getSelected().size() == 1) { + enabled = isDownloadable(getLastSelected()); + } + setEnabled(enabled); + } + + public void onDownlownClick(AjaxRequestTarget target, String ext) { + BaseFileItem fi = getLastSelected(); + File f = ext == null && (Type.IMAGE == fi.getType() || Type.PRESENTATION == fi.getType()) + ? fi.getOriginal() : fi.getFile(ext); + if (f != null && f.exists()) { + dwnldFile = f; + downloader.initiate(target); + } + } + }; + buttons.setOutputMarkupId(true); + form.add(buttons.add(download, new ListView<>("other-buttons", newOtherButtons("button")) { + private static final long serialVersionUID = 1L; + + @Override + protected void populateItem(ListItem<AbstractLink> item) { + item.add(item.getModelObject()); + } + })); } private ConfirmableAjaxBorder getTrashBorder() { @@ -428,10 +467,6 @@ public abstract class FileTreePanel extends Panel { return false; } - private static boolean isDownloadable(BaseFileItem f) { - return !f.isReadOnly() && (f.getType() == Type.PRESENTATION || f.getType() == Type.IMAGE); - } - public void select(BaseFileItem fi, AjaxRequestTarget target, boolean shift, boolean ctrl) { updateSelected(target); //all previously selected are in update list if (ctrl) { @@ -467,10 +502,14 @@ public abstract class FileTreePanel extends Panel { } updateSelected(target); //all finally selected are in the update list if (target != null) { - target.add(trashBorder, download.setVisible(isDownloadable(lastSelected))); + target.add(trashBorder, buttons); } } + protected List<AbstractLink> newOtherButtons(String markupId) { + return List.of(); + } + @Override protected void onDetach() { homeSize.detach(); diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/HashPage.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/HashPage.java index c6fedca..f3c42ad 100644 --- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/HashPage.java +++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/HashPage.java @@ -199,7 +199,7 @@ public class HashPage extends BaseInitedPage implements IUpdatable { error = false; } } - add(recContainer.add(vi.setShowShare(false).setOutputMarkupPlaceholderTag(true), + add(recContainer.add(vi.setOutputMarkupPlaceholderTag(true), vp.setOutputMarkupPlaceholderTag(true)), new InvitationPasswordDialog("i-pass", this)); remove(urlParametersReceivingBehavior); add(new IconTextModal("access-denied") diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/RecordingsPanel.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/RecordingsPanel.html index eaee8ef..91a10c4 100644 --- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/RecordingsPanel.html +++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/RecordingsPanel.html @@ -28,5 +28,6 @@ <div wicket:id="video"></div> </div> <div wicket:id="addFolder"></div> + <div wicket:id="invitation"></div> </wicket:panel> </html> 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 8579b09..6c80fa9 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 @@ -19,24 +19,51 @@ package org.apache.openmeetings.web.user.record; import static org.apache.openmeetings.util.OmFileHelper.getHumanSize; +import static org.apache.openmeetings.util.OmFileHelper.getRecordingChunk; import static org.apache.openmeetings.web.app.WebSession.getUserId; +import java.util.List; +import java.util.stream.Collectors; + +import org.apache.openmeetings.core.converter.IRecordingConverter; +import org.apache.openmeetings.core.converter.InterviewConverter; +import org.apache.openmeetings.core.converter.RecordingConverter; +import org.apache.openmeetings.db.dao.record.RecordingChunkDao; import org.apache.openmeetings.db.dao.record.RecordingDao; import org.apache.openmeetings.db.dto.record.RecordingContainerData; import org.apache.openmeetings.db.entity.file.BaseFileItem; +import org.apache.openmeetings.db.entity.record.Recording; +import org.apache.openmeetings.db.entity.record.Recording.Status; +import org.apache.openmeetings.db.entity.record.RecordingChunk; +import org.apache.openmeetings.web.common.InvitationDialog; import org.apache.openmeetings.web.common.NameDialog; import org.apache.openmeetings.web.common.UserBasePanel; import org.apache.openmeetings.web.common.tree.FileTreePanel; import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.markup.html.link.AbstractLink; +import org.apache.wicket.model.Model; +import org.apache.wicket.model.ResourceModel; import org.apache.wicket.spring.injection.annot.SpringBean; +import de.agilecoders.wicket.core.markup.html.bootstrap.button.BootstrapAjaxLink; +import de.agilecoders.wicket.core.markup.html.bootstrap.button.Buttons; + public class RecordingsPanel extends UserBasePanel { private static final long serialVersionUID = 1L; private final VideoPlayer video = new VideoPlayer("video"); private final VideoInfo info = new VideoInfo("info"); private FileTreePanel fileTree; + private InvitationDialog invite; + private RecordingInvitationForm rif = new RecordingInvitationForm("form"); + @SpringBean private RecordingDao recDao; + @SpringBean + private InterviewConverter interviewConverter; + @SpringBean + private RecordingConverter recordingConverter; + @SpringBean + private RecordingChunkDao chunkDao; public RecordingsPanel(String id) { super(id); @@ -70,8 +97,71 @@ public class RecordingsPanel extends UserBasePanel { video.update(target, f); info.update(target, f); } + + @Override + protected List<AbstractLink> newOtherButtons(String markupId) { + return List.of(new BootstrapAjaxLink<>(markupId, Model.of(""), Buttons.Type.Outline_Warning, new ResourceModel("1600")) { + private static final long serialVersionUID = 1L; + private boolean isInterview = false; + + @Override + protected void onConfigure() { + super.onConfigure(); + boolean enabled = false; + isInterview = false; + if (getSelected().size() == 1 && BaseFileItem.Type.RECORDING == getLastSelected().getType()) { + Recording r = (Recording)getLastSelected(); + isInterview = r.isInterview(); + + if (r.getOwnerId() != null && r.getOwnerId().equals(getUserId()) && r.getStatus() != Status.RECORDING && r.getStatus() != Status.CONVERTING) { + List<RecordingChunk> chunks = chunkDao.getByRecording(r.getId()) + .stream() + .filter(chunk -> r.getRoomId() == null || !getRecordingChunk(r.getRoomId(), chunk.getStreamName()).exists()) + .collect(Collectors.toList()); + enabled = !chunks.isEmpty(); + } + } + setEnabled(enabled); + } + + @Override + public void onClick(AjaxRequestTarget target) { + final IRecordingConverter converter = isInterview ? interviewConverter : recordingConverter; + new Thread() { + @Override + public void run() { + 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; + + @Override + protected void onConfigure() { + super.onConfigure(); + boolean enabled = false; + if (getSelected().size() == 1 && BaseFileItem.Type.RECORDING == getLastSelected().getType()) { + Recording r = (Recording)getLastSelected(); + if (!r.isReadOnly() && r.exists()) { + enabled = true; + } + } + setEnabled(enabled); + } + + @Override + public void onClick(AjaxRequestTarget target) { + rif.setRecordingId(getLastSelected().getId()); + invite.updateModel(target); + invite.show(target); + } + }); + } }); add(video, info, addFolder); + add(invite = new InvitationDialog("invitation", rif)); + rif.setDialog(invite); super.onInitialize(); } diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/VideoInfo.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/VideoInfo.html index 8fb4d72..0f8f0d4 100644 --- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/VideoInfo.html +++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/VideoInfo.html @@ -40,10 +40,6 @@ <div class="value col-9" wicket:id="roomName"></div> </div> </div> - <span wicket:id="downloadBtn"></span> - <button wicket:id="re-convert"></button> - <button wicket:id="share"></button> </form> - <div wicket:id="invitation"></div> </wicket:panel> </html> diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/VideoInfo.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/VideoInfo.java index a7f0811..e6887c7 100644 --- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/VideoInfo.java +++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/VideoInfo.java @@ -18,128 +18,27 @@ */ package org.apache.openmeetings.web.user.record; -import static java.time.Duration.ZERO; -import static org.apache.openmeetings.util.OmFileHelper.EXTENSION_MP4; -import static org.apache.openmeetings.util.OmFileHelper.getRecordingChunk; -import static org.apache.openmeetings.web.app.WebSession.getUserId; - -import java.io.File; -import java.nio.file.Path; -import java.util.List; -import java.util.stream.Collectors; - -import org.apache.openmeetings.core.converter.IRecordingConverter; import org.apache.openmeetings.core.converter.InterviewConverter; import org.apache.openmeetings.core.converter.RecordingConverter; import org.apache.openmeetings.db.dao.record.RecordingChunkDao; import org.apache.openmeetings.db.dao.room.RoomDao; import org.apache.openmeetings.db.entity.file.BaseFileItem; import org.apache.openmeetings.db.entity.record.Recording; -import org.apache.openmeetings.db.entity.record.Recording.Status; -import org.apache.openmeetings.db.entity.record.RecordingChunk; import org.apache.openmeetings.db.entity.room.Room; -import org.apache.openmeetings.web.common.InvitationDialog; import org.apache.wicket.ajax.AjaxRequestTarget; -import org.apache.wicket.extensions.ajax.AjaxDownloadBehavior; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.form.Form; -import org.apache.wicket.markup.html.link.AbstractLink; import org.apache.wicket.markup.html.panel.Panel; import org.apache.wicket.model.CompoundPropertyModel; import org.apache.wicket.model.IModel; import org.apache.wicket.model.Model; -import org.apache.wicket.model.ResourceModel; -import org.apache.wicket.request.resource.IResource; -import org.apache.wicket.resource.FileSystemResource; import org.apache.wicket.spring.injection.annot.SpringBean; -import de.agilecoders.wicket.core.markup.html.bootstrap.button.BootstrapAjaxButton; -import de.agilecoders.wicket.core.markup.html.bootstrap.button.BootstrapAjaxLink; -import de.agilecoders.wicket.core.markup.html.bootstrap.button.Buttons; -import de.agilecoders.wicket.core.markup.html.bootstrap.button.dropdown.SplitButton; -import de.agilecoders.wicket.core.markup.html.bootstrap.image.IconType; -import de.agilecoders.wicket.extensions.markup.html.bootstrap.icon.FontAwesome5IconType; - public class VideoInfo extends Panel { private static final long serialVersionUID = 1L; private final Form<Void> form = new Form<>("form"); - private final SplitButton downloadBtn = new SplitButton("downloadBtn", Model.of("")) { - private static final long serialVersionUID = 1L; - - private AbstractLink createLink(String markupId, IModel<String> model, String ext) { - return new BootstrapAjaxLink<>(markupId, model, Buttons.Type.Outline_Primary, model) { - private static final long serialVersionUID = 1L; - - @Override - public boolean isEnabled() { - BaseFileItem r = rm.getObject(); - return r != null && r.exists(EXTENSION_MP4) && !r.isReadOnly(); - } - - @Override - public void onClick(AjaxRequestTarget target) { - download.initiate(target); - } - }.setIconType(FontAwesome5IconType.download_s); - } - - @Override - protected List<AbstractLink> newSubMenuButtons(String buttonMarkupId) { - return List.of(createLink(buttonMarkupId, Model.of(EXTENSION_MP4), EXTENSION_MP4)); - } - - @Override - protected AbstractLink newBaseButton(String markupId, IModel<String> labelModel, IModel<IconType> iconTypeModel) { - return createLink(markupId, Model.of(EXTENSION_MP4), EXTENSION_MP4); - } - }; - private final BootstrapAjaxButton reConvert = new BootstrapAjaxButton("re-convert", new ResourceModel("1600"), form, Buttons.Type.Outline_Warning) { - private static final long serialVersionUID = 1L; - - @Override - protected void onSubmit(AjaxRequestTarget target) { - final IRecordingConverter converter = isInterview ? interviewConverter : recordingConverter; - new Thread() { - @Override - public void run() { - converter.startConversion(rm.getObject()); - } - }.start(); - } - }; - private final AjaxDownloadBehavior download = new AjaxDownloadBehavior(new IResource() { - private static final long serialVersionUID = 1L; - - @Override - public void respond(Attributes attributes) { - File f = rm.getObject().getFile(EXTENSION_MP4); - new FileSystemResource(f.toPath()) { - private static final long serialVersionUID = 1L; - - @Override - protected ResourceResponse createResourceResponse(Attributes attr, Path path) { - ResourceResponse response = super.createResourceResponse(attr, path); - response.setCacheDuration(ZERO); - return response; - } - }.respond(attributes); - } - }); private final IModel<Recording> rm = new CompoundPropertyModel<>(new Recording()); private final IModel<String> roomName = Model.of((String)null); - private boolean isInterview = false; - private InvitationDialog invite; - RecordingInvitationForm rif = new RecordingInvitationForm("form"); - private final BootstrapAjaxButton share = new BootstrapAjaxButton("share", new ResourceModel("button.label.share"), form, Buttons.Type.Outline_Success) { - private static final long serialVersionUID = 1L; - - @Override - protected void onSubmit(AjaxRequestTarget target) { - rif.setRecordingId(rm.getObject().getId()); - invite.updateModel(target); - invite.show(target); - } - }; @SpringBean private InterviewConverter interviewConverter; @SpringBean @@ -155,13 +54,9 @@ public class VideoInfo extends Panel { } public VideoInfo update(AjaxRequestTarget target, BaseFileItem _r) { - boolean reConvEnabled = false; - boolean exists = false; if (_r instanceof Recording) { Recording r = (Recording)_r; - isInterview = r.isInterview(); rm.setObject(r); - exists = r.exists(); try { String name = null; if (r.getRoomId() != null) { @@ -174,18 +69,7 @@ public class VideoInfo extends Panel { } catch (Exception e) { //no-op } - - if (r.getOwnerId() != null && r.getOwnerId().equals(getUserId()) && r.getStatus() != Status.RECORDING && r.getStatus() != Status.CONVERTING) { - List<RecordingChunk> chunks = chunkDao.getByRecording(r.getId()) - .stream() - .filter(chunk -> r.getRoomId() == null || !getRecordingChunk(r.getRoomId(), chunk.getStreamName()).exists()) - .collect(Collectors.toList()); - reConvEnabled = !chunks.isEmpty(); - } } - reConvert.setEnabled(reConvEnabled); - downloadBtn.setEnabled(exists && !_r.isReadOnly()); - share.setEnabled(exists && !_r.isReadOnly()); if (target != null) { target.add(form); } @@ -207,20 +91,8 @@ public class VideoInfo extends Panel { form.add(new Label("name") , new Label("duration") , new Label("recordEnd") - , new Label("roomName", roomName) - , downloadBtn.setEnabled(false) - , reConvert.setIconType(FontAwesome5IconType.sync_alt_s).setEnabled(false) - , share.setIconType(FontAwesome5IconType.share_alt_s).setEnabled(false)); - add(download); - add(invite = new InvitationDialog("invitation", rif)); - rif.setDialog(invite); + , new Label("roomName", roomName)); update(null, null); } - - public VideoInfo setShowShare(boolean visible) { - reConvert.setVisible(visible); - share.setVisible(visible); - return this; - } } diff --git a/openmeetings-web/src/main/webapp/css/raw-tree.css b/openmeetings-web/src/main/webapp/css/raw-tree.css index d4eef5c..fdd1983 100644 --- a/openmeetings-web/src/main/webapp/css/raw-tree.css +++ b/openmeetings-web/src/main/webapp/css/raw-tree.css @@ -24,6 +24,10 @@ .file-tree .footer .sizes .size { padding-left: 5px; } +.file-tree .footer .buttons .other-buttons { + display: inline-block; + margin: 0 2px; +} /* Calc width with default for max level of 7 */ .file-tree .file.item .name , .file-tree .file.item .name span diff --git a/openmeetings-web/src/main/webapp/css/raw-variables.css b/openmeetings-web/src/main/webapp/css/raw-variables.css index 3a6296a..405805a 100644 --- a/openmeetings-web/src/main/webapp/css/raw-variables.css +++ b/openmeetings-web/src/main/webapp/css/raw-variables.css @@ -35,11 +35,11 @@ body.no-menu { --actions-height: 40px; } .recording-panel { - --info-height: 125px; + --info-height: 90px; } .file-tree { --tree-header-height: 36px; - --tree-footer-height: 80px; + --tree-footer-height: 50px; } .main.room { --header-height: 0px; diff --git a/openmeetings-web/src/test/java/org/apache/openmeetings/webservice/AbstractWebServiceTest.java b/openmeetings-web/src/test/java/org/apache/openmeetings/webservice/AbstractWebServiceTest.java index 615c464..bf68ded 100644 --- a/openmeetings-web/src/test/java/org/apache/openmeetings/webservice/AbstractWebServiceTest.java +++ b/openmeetings-web/src/test/java/org/apache/openmeetings/webservice/AbstractWebServiceTest.java @@ -106,7 +106,7 @@ public class AbstractWebServiceTest { AbstractSpringTest.init(); tomcat = new Tomcat(); Connector connector = new Connector("HTTP/1.1"); - connector.setAttribute("address", InetAddress.getByName(HOST).getHostAddress()); + connector.setProperty("address", InetAddress.getByName(HOST).getHostAddress()); connector.setPort(0); tomcat.getService().addConnector(connector); tomcat.setConnector(connector);