Make File Upload plugin as internal and skip it's loading from plugins dir

This commit is contained in:
Sergey Ponomarev
2026-06-09 23:53:10 +03:00
parent 33d17782cb
commit b794379364
9 changed files with 252 additions and 58 deletions

View File

@ -77,6 +77,7 @@ public class PluginManager implements MainWindowListener
{
public static final Map<String, String> INCOMPATIBLE_PLUGINS = Map.of(
// normalizePluginName("OTR Plugin"), "0.4 Beta"
normalizePluginName("Http File Upload Plugin"), ""
);
private final List<Plugin> plugins = new ArrayList<>();
@ -318,7 +319,7 @@ public class PluginManager implements MainWindowListener
String lower = normalizePluginName(publicPlugin.getName());
// Don't load the plugin if it's known to be incompatible with this version of Spark.
String incompatibleVersion = INCOMPATIBLE_PLUGINS.get(lower);
if (incompatibleVersion != null && incompatibleVersion.compareTo(publicPlugin.getVersion()) >= 0) {
if (incompatibleVersion != null && (incompatibleVersion.isEmpty() || incompatibleVersion.compareTo(publicPlugin.getVersion()) >= 0)) {
Log.warning("Not loading plugin " + publicPlugin.getName() + " (version " + publicPlugin.getVersion() + ") as it is incompatible with this version of Spark.");
return null;
}

View File

@ -19,6 +19,7 @@ public class InternalPlugins {
new PublicPlugin("Emoticon Plugin", "org.jivesoftware.sparkimpl.plugin.emoticons.EmoticonPlugin", "1.1"),
new PublicPlugin("Notes Plugin", "org.jivesoftware.sparkimpl.plugin.scratchpad.ScratchPadPlugin", "1.1"),
new PublicPlugin("Buzz Plugin", "org.jivesoftware.sparkimpl.plugin.alerts.BuzzPlugin", "1.1"),
new PublicPlugin("Http File Upload Plugin", "org.jivesoftware.sparkimpl.plugin.fileupload.SparkFileUploadPlugin", "1.1"),
new PublicPlugin("Notifications Plugin", "org.jivesoftware.sparkimpl.preference.notifications.NotificationPlugin", "1.1"),
new PublicPlugin("Shortcut Plugin", "org.jivesoftware.sparkimpl.plugin.chat.ShortcutPlugin", "1.1"),
new PublicPlugin("History Plugin", "org.jivesoftware.sparkimpl.plugin.history.ConversationHistoryPlugin", "1.1"),

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.jivesoftware.spark.plugin.fileupload;
package org.jivesoftware.sparkimpl.plugin.fileupload;
import org.jivesoftware.resource.Res;
import org.jivesoftware.resource.SparkRes;
@ -27,22 +27,19 @@ import org.jivesoftware.smackx.httpfileupload.UploadService;
import org.jivesoftware.spark.component.RolloverButton;
import org.jivesoftware.spark.ui.ChatRoom;
import org.jivesoftware.spark.util.GraphicUtils;
import org.jivesoftware.spark.util.SwingWorker;
import org.jivesoftware.spark.util.log.Log;
import org.jivesoftware.sparkimpl.plugin.filetransfer.transfer.ui.TransferUtils;
import javax.swing.SwingUtilities;
import java.awt.FileDialog;
import java.awt.Frame;
import java.io.File;
import java.net.URL;
import java.time.Duration;
import java.time.Instant;
import static org.jivesoftware.smack.XMPPException.XMPPErrorException;
import static org.jivesoftware.smack.packet.StanzaError.Condition.not_acceptable;
import static org.jivesoftware.smack.packet.StanzaError.Condition.resource_constraint;
import static org.jivesoftware.spark.ChatManager.ERROR_COLOR;
import static org.jivesoftware.spark.ChatManager.NOTIFICATION_COLOR;
public class ChatRoomDecorator {
private final HttpFileUploadManager httpFileUploadManager;
@ -74,9 +71,16 @@ public class ChatRoomDecorator {
fd.setVisible(true);
File[] files = fd.getFiles();
for (File file : files) {
SwingUtilities.invokeLater(() -> handleUpload(file, room));
}
SwingWorker worker = new SwingWorker() {
@Override
public Object construct() {
for (File file : files) {
handleUpload(file, room);
}
return null;
}
};
worker.start();
}
private void handleUpload(File file, ChatRoom room) {
@ -97,14 +101,7 @@ public class ChatRoomDecorator {
}
}
try {
Instant start = Instant.now();
URL uploadedFile = httpFileUploadManager.uploadFile(file, (uploadedBytes, totalBytes) -> {
if (Duration.between(start, Instant.now()).toSeconds() < 10) {
return;
}
long progress = totalBytes > 0 ? uploadedBytes / totalBytes : 100;
room.getTranscriptWindow().insertNotificationMessage(progress + "%", NOTIFICATION_COLOR);
});
URL uploadedFile = httpFileUploadManager.uploadFile(file);
broadcastUploadUrl(uploadedFile.toString());
} catch (Exception e) {
String errMsg = e.getMessage();

View File

@ -0,0 +1,228 @@
/**
* Copyright (C) 2004-2011 Jive Software. 2026 Ignite Realtime Foundation. All rights reserved.
*
* Licensed 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.jivesoftware.sparkimpl.plugin.fileupload;
import org.jivesoftware.resource.Res;
import org.jivesoftware.resource.SparkRes;
import org.jivesoftware.smackx.filetransfer.FileTransfer.Status;
import org.jivesoftware.smackx.filetransfer.OutgoingFileTransfer;
import org.jivesoftware.spark.SparkManager;
import org.jivesoftware.spark.component.FileDragLabel;
import org.jivesoftware.spark.ui.ContactItem;
import org.jivesoftware.spark.ui.ContactList;
import org.jivesoftware.spark.util.ByteFormat;
import org.jivesoftware.spark.util.GraphicUtils;
import org.jivesoftware.spark.util.SwingWorker;
import org.jivesoftware.spark.util.log.Log;
import org.jivesoftware.sparkimpl.plugin.filetransfer.transfer.ui.TransferUtils;
import org.jivesoftware.sparkimpl.settings.Sizes;
import org.jxmpp.jid.EntityFullJid;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Desktop;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import static java.awt.GridBagConstraints.NONE;
import static java.awt.GridBagConstraints.NORTHWEST;
public class FileUploadChatComponent extends JPanel {
private final FileDragLabel imageLabel = new FileDragLabel();
private final JLabel titleLabel = new JLabel();
private final JLabel fileLabel = new JLabel();
private final JProgressBar progressBar = new JProgressBar();
private File fileToSend;
private final JLabel progressLabel = new JLabel();
private long _startTime;
public FileUploadChatComponent() {
setLayout(new GridBagLayout());
setBackground(new Color(250, 249, 242));
Insets insets = new Insets(5, 5, 5, 5);
add(imageLabel, new GridBagConstraints(0, 0, 1, 3, 0, 0, NORTHWEST, NONE, insets, 0, 0));
titleLabel.setFont(new Font("Dialog", Font.BOLD, 11));
titleLabel.setForeground(new Color(211, 174, 102));
add(titleLabel, new GridBagConstraints(1, 0, 2, 1, 1, 0, NORTHWEST, NONE, insets, 0, 0));
add(fileLabel, new GridBagConstraints(1, 1, 2, 1, 1, 0, GridBagConstraints.WEST, NONE, new Insets(0, 5, 5, 5), 0, 0));
setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, Color.white));
}
public void sendFile(final OutgoingFileTransfer transfer, final EntityFullJid jid, final String nickname) {
String fileName = transfer.getFileName();
String filePath = transfer.getFilePath();
long fileSize = transfer.getFileSize();
ByteFormat format = new ByteFormat();
String fileSizeString = format.format(fileSize);
fileToSend = new File(transfer.getFilePath());
imageLabel.setFile(fileToSend);
fileLabel.setText(fileName + " (" + fileSizeString + ")");
ContactList contactList = SparkManager.getWorkspace().getContactList();
ContactItem contactItem = contactList.getContactItemByJID(jid);
titleLabel.setText(Res.getString("message.transfer.waiting.on.user", contactItem.getDisplayName()));
if (isImage(fileName)) {
try {
URL imageURL = new File(transfer.getFilePath()).toURI().toURL();
ImageIcon image = new ImageIcon(imageURL);
image = GraphicUtils.scaleImageIcon(image, Sizes.Transfer.THUMBNAIL, Sizes.Transfer.THUMBNAIL);
imageLabel.setIcon(image);
} catch (MalformedURLException e) {
Log.error("Could not locate image.", e);
imageLabel.setIcon(SparkRes.getImageIcon(SparkRes.Icon.DOCUMENT_INFO_32x32));
}
} else {
File file = new File(transfer.getFilePath());
Icon icon = GraphicUtils.getIcon(file);
imageLabel.setIcon(icon);
}
progressBar.setMaximum(100);
progressBar.setVisible(false);
progressBar.setStringPainted(true);
add(progressBar, new GridBagConstraints(1, 2, 2, 1, 1, 0, GridBagConstraints.WEST, NONE, new Insets(0, 5, 0, 5), 150, 0));
add(progressLabel, new GridBagConstraints(1, 3, 2, 1, 1, 0, GridBagConstraints.WEST, NONE, new Insets(0, 5, 0, 5), 150, 0));
SwingWorker worker = new SwingWorker() {
@Override
public Object construct() {
while (true) {
try {
if (transfer.getBytesSent() > 0 && _startTime == 0) {
_startTime = System.currentTimeMillis();
}
long startTime = System.currentTimeMillis();
long startByte = transfer.getBytesSent();
Thread.sleep(500);
long endTime = System.currentTimeMillis();
long endByte = transfer.getBytesSent();
long timeDiff = endTime - startTime;
long byteDiff = endByte - startByte;
updateBar(transfer, nickname, TransferUtils.calculateSpeed(byteDiff, timeDiff));
} catch (InterruptedException e) {
Log.error("Unable to sleep thread.", e);
return null;
}
}
}
@Override
public void finished() {
updateBar(transfer, nickname, "??MB/s");
}
};
worker.start();
makeClickable(imageLabel);
makeClickable(titleLabel);
}
private void makeClickable(final JLabel label) {
label.setToolTipText(Res.getString("message.click.to.open"));
label.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
openFile(fileToSend);
}
@Override
public void mouseEntered(MouseEvent e) {
label.setCursor(new Cursor(Cursor.HAND_CURSOR));
}
@Override
public void mouseExited(MouseEvent e) {
label.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
});
}
private void openFile(File downloadedFile) {
try {
Desktop.getDesktop().open(downloadedFile);
} catch (IOException e) {
Log.error("An error occurred while trying to open downloaded file: " + downloadedFile, e);
}
}
private void updateBar(final OutgoingFileTransfer transfer, String nickname, String kBperSecond) {
}
private static class TransferButton extends JButton {
public TransferButton() {
decorate();
}
/**
* Decorates the button with the appropriate UI configurations.
*/
private void decorate() {
setBorderPainted(false);
setOpaque(true);
setContentAreaFilled(false);
setMargin(new Insets(1, 1, 1, 1));
}
}
private boolean isImage(String fileName) {
fileName = fileName.toLowerCase();
String[] imageTypes = {"jpeg", "gif", "jpg", "png"};
for (String imageType : imageTypes) {
if (fileName.endsWith(imageType)) {
return true;
}
}
return false;
}
private void showAlert(boolean alert) {
if (alert) {
titleLabel.setForeground(new Color(211, 174, 102));
setBackground(new Color(250, 249, 242));
} else {
setBackground(new Color(239, 245, 250));
titleLabel.setForeground(new Color(65, 139, 179));
}
}
}

View File

@ -15,7 +15,7 @@
*/
package org.jivesoftware.spark.plugin.fileupload;
package org.jivesoftware.sparkimpl.plugin.fileupload;
import org.jivesoftware.smackx.httpfileupload.HttpFileUploadManager;
import org.jivesoftware.spark.ChatManager;
@ -30,7 +30,13 @@ import java.util.HashMap;
import java.util.Map;
public class SparkFileUploadPlugin implements Plugin, ChatRoomListener {
/**
* Http File Upload Plugin.
* Allows users to share files by uploading to a server (via XEP-0363).
*
* @author Dele Olajide
*/
public class SparkFileUploadPlugin implements Plugin, ChatRoomListener {
private HttpFileUploadManager httpFileUploadManager;
private final Map<EntityJid, ChatRoomDecorator> decorators = new HashMap<>();

View File

@ -1,26 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.igniterealtime.spark.plugins</groupId>
<artifactId>plugin</artifactId>
<version>3.1.0-SNAPSHOT</version>
<relativePath>../plugin/pom.xml</relativePath>
</parent>
<artifactId>fileupload</artifactId>
<version>0.1</version>
<name>Http File Upload Plugin</name>
<description>Allows users to share files by uploading to a server (via XEP-0363).</description>
<contributors>
<contributor>
<name>Dele Olajide</name>
<roles>
<role>Author</role>
</roles>
</contributor>
</contributors>
</project>

View File

@ -1,12 +0,0 @@
<plugin>
<name>${project.name}</name>
<version>${project.version}</version>
<description>${project.description}</description>
<author>Dele Olajide</author>
<homePage>https://IgniteRealtime.org</homePage>
<email>support@IgniteRealtime.org</email>
<class>org.jivesoftware.spark.plugin.fileupload.SparkFileUploadPlugin</class>
<minSparkVersion>3.1.0</minSparkVersion>
<os>Windows,Linux,Mac</os>
<java>11</java>
</plugin>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 413 B

View File

@ -61,7 +61,6 @@
<!-- <module>plugins/battleships</module>-->
<module>plugins/apple</module>
<module>plugins/fastpath</module>
<module>plugins/fileupload</module>
<module>plugins/flashing</module>
<module>plugins/growl</module>
<!-- <module>plugins/phone</module>-->