diff --git a/gui/griffon-app/conf/Config.groovy b/gui/griffon-app/conf/Config.groovy index ab052990..bfa961ae 100644 --- a/gui/griffon-app/conf/Config.groovy +++ b/gui/griffon-app/conf/Config.groovy @@ -218,4 +218,9 @@ mvcGroups { view = 'com.muwire.gui.resultdetails.CollectionListView' controller = 'com.muwire.gui.resultdetails.CollectionListController' } + 'publish-preview' { + model = 'com.muwire.gui.PublishPreviewModel' + view = 'com.muwire.gui.PublishPreviewView' + controller = 'com.muwire.gui.PublishPreviewController' + } } diff --git a/gui/griffon-app/controllers/com/muwire/gui/MainFrameController.groovy b/gui/griffon-app/controllers/com/muwire/gui/MainFrameController.groovy index b8a48291..28143a1f 100644 --- a/gui/griffon-app/controllers/com/muwire/gui/MainFrameController.groovy +++ b/gui/griffon-app/controllers/com/muwire/gui/MainFrameController.groovy @@ -748,11 +748,10 @@ class MainFrameController { if (selectedFiles == null || selectedFiles.isEmpty()) return - long now = System.currentTimeMillis() - selectedFiles.stream().filter({!it.isPublished()}).forEach({ - it.publish(now) - model.core.eventBus.publish(new UIFilePublishedEvent(sf : it)) - }) + def params = [:] + params.core = model.core + params.requested = selectedFiles + mvcGroup.createMVCGroup("publish-preview",params).destroy() view.refreshSharedFiles() } diff --git a/gui/griffon-app/controllers/com/muwire/gui/PublishPreviewController.groovy b/gui/griffon-app/controllers/com/muwire/gui/PublishPreviewController.groovy new file mode 100644 index 00000000..0a6b1103 --- /dev/null +++ b/gui/griffon-app/controllers/com/muwire/gui/PublishPreviewController.groovy @@ -0,0 +1,34 @@ +package com.muwire.gui + +import com.muwire.core.SharedFile +import com.muwire.core.filefeeds.UIFilePublishedEvent +import griffon.core.artifact.GriffonController +import griffon.core.controller.ControllerAction +import griffon.inject.MVCMember +import griffon.metadata.ArtifactProviderFor + +import javax.annotation.Nonnull + +@ArtifactProviderFor(GriffonController) +class PublishPreviewController { + + @MVCMember @Nonnull + PublishPreviewModel model + @MVCMember @Nonnull + PublishPreviewView view + + @ControllerAction + void publish() { + final long now = System.currentTimeMillis() + for (SharedFile sf : model.toPublish) { + sf.publish(now) + model.core.eventBus.publish(new UIFilePublishedEvent(sf: sf)) + } + cancel() + } + + @ControllerAction + void cancel() { + view.dialog.setVisible(false) + } +} diff --git a/gui/griffon-app/i18n/messages.properties b/gui/griffon-app/i18n/messages.properties index ce6892ee..1caa5817 100644 --- a/gui/griffon-app/i18n/messages.properties +++ b/gui/griffon-app/i18n/messages.properties @@ -661,6 +661,11 @@ PASTE=Paste ## My Feed dialog MY_FEED=My Feed +## Publish preview dialog +PUBLISH_PREVIEW_TITLE=Preview files to be published +PUBLISH_PREVIEW_TO_PUBLISH=List of files to be published now +PUBLISH_PREVIEW_ALREADY_PUBLISHED=List of files already published + ## Tooltips TOOLTIP_FILE_FEED_DISABLED=Your file feed is disabled TOOLTIP_VIEW_FILE_FEED=View your file feed diff --git a/gui/griffon-app/models/com/muwire/gui/PublishPreviewModel.groovy b/gui/griffon-app/models/com/muwire/gui/PublishPreviewModel.groovy new file mode 100644 index 00000000..936a9da7 --- /dev/null +++ b/gui/griffon-app/models/com/muwire/gui/PublishPreviewModel.groovy @@ -0,0 +1,30 @@ +package com.muwire.gui + +import com.muwire.core.Core +import com.muwire.core.SharedFile +import griffon.core.artifact.GriffonModel +import griffon.metadata.ArtifactProviderFor + +import java.util.function.Predicate +import java.util.stream.Collectors +import java.util.stream.Stream + +@ArtifactProviderFor(GriffonModel) +class PublishPreviewModel { + + + Core core + List requested + + SharedFile[] toPublish, alreadyPublished + + void mvcGroupInit(Map attributes) { + Stream stream = requested.stream() + if (requested.size() > 1000) + stream = stream.parallel() + def map = stream. + collect(Collectors.partitioningBy({it.isPublished()} as Predicate)) + toPublish = map.get(false).toArray(new SharedFile[0]) + alreadyPublished = map.get(true).toArray(new SharedFile[0]) + } +} diff --git a/gui/griffon-app/views/com/muwire/gui/PublishPreviewView.groovy b/gui/griffon-app/views/com/muwire/gui/PublishPreviewView.groovy new file mode 100644 index 00000000..003e5da7 --- /dev/null +++ b/gui/griffon-app/views/com/muwire/gui/PublishPreviewView.groovy @@ -0,0 +1,104 @@ +package com.muwire.gui + +import griffon.core.artifact.GriffonView +import griffon.inject.MVCMember +import griffon.metadata.ArtifactProviderFor + +import javax.annotation.Nonnull +import javax.swing.JDialog +import javax.swing.JTable +import javax.swing.border.Border +import java.awt.BorderLayout +import java.awt.event.WindowAdapter +import java.awt.event.WindowEvent + +import static com.muwire.gui.Translator.trans + +@ArtifactProviderFor(GriffonView) +class PublishPreviewView { + @MVCMember @Nonnull + FactoryBuilderSupport builder + @MVCMember @Nonnull + PublishPreviewModel model + + def mainFrame + JDialog dialog + def p + + JTable toPublishTable, alreadyPublishedTable + + void initUI() { + mainFrame = application.windowManager.findWindow("main-frame") + int rowHeight = application.context.get("row-height") + String title = trans("PUBLISH_PREVIEW_TITLE") + dialog = new JDialog(mainFrame, title, true) + dialog.setResizable(true) + + int rows = 1 + if (model.toPublish.length > 0 && model.alreadyPublished.length > 0) + rows = 2 + p = builder.panel(preferredSize: [800, rows * 300]) { + borderLayout() + panel(constraints: BorderLayout.CENTER) { + gridLayout(rows: rows, cols: 1) + if (model.toPublish.length > 0) { + panel(border: etchedBorder()) { + borderLayout() + panel(constraints: BorderLayout.NORTH) { + label(text: trans("PUBLISH_PREVIEW_TO_PUBLISH")) + } + scrollPane(constraints: BorderLayout.CENTER) { + toPublishTable = table(autoCreateRowSorter: true, rowHeight: rowHeight) { + tableModel(list: model.toPublish) { + closureColumn(header: trans("NAME"), preferredWidth: 500, type: String, read: { HTMLSanitizer.sanitize(it.getCachedPath()) }) + closureColumn(header: trans("SIZE"), preferredWidth: 100, type: Long, read: { it.getCachedLength() }) + } + } + } + + } + } + if (model.alreadyPublished.length > 0) { + panel(border: etchedBorder()) { + borderLayout() + panel(constraints: BorderLayout.NORTH) { + label(text: trans("PUBLISH_PREVIEW_ALREADY_PUBLISHED")) + } + scrollPane(constraints: BorderLayout.CENTER) { + alreadyPublishedTable = table(autoCreateRowSorter : true, rowHeight: rowHeight) { + tableModel(list : model.alreadyPublished) { + closureColumn(header : trans("NAME"), preferredWidth: 500, type : String, read : { HTMLSanitizer.sanitize(it.getCachedPath())}) + closureColumn(header : trans("SIZE"), preferredWidth: 100, type : Long, read : {it.getCachedLength() }) + closureColumn(header: trans("DATE"), preferredWidth: 200, type: Long, read: { it.getPublishedTimestamp() }) + } + } + } + } + } + } + panel(constraints: BorderLayout.SOUTH) { + button(text : trans("PUBLISH"), enabled : model.toPublish.length > 0, publishAction) + button(text : trans("CANCEL"), cancelAction) + } + } + + if (toPublishTable != null) + toPublishTable.columnModel.getColumn(1).setCellRenderer(new SizeRenderer()) + if (alreadyPublishedTable != null) { + alreadyPublishedTable.columnModel.with { + getColumn(1).setCellRenderer(new SizeRenderer()) + getColumn(2).setCellRenderer(new DateRenderer()) + } + } + } + + void mvcGroupInit(Map args) { + dialog.with { + getContentPane().add(p) + pack() + setLocationRelativeTo(mainFrame) + setDefaultCloseOperation(DISPOSE_ON_CLOSE) + show() + } + } +}