Added ability to save attachments

This commit is contained in:
delvh 2020-07-27 12:00:49 +02:00
parent 1cdad2df0b
commit e216152e6b
5 changed files with 81 additions and 24 deletions

View File

@ -27,6 +27,11 @@ public final class AudioRecorder {
*/ */
public static final AudioFormat DEFAULT_AUDIO_FORMAT = new AudioFormat(16000, 16, 1, true, false); public static final AudioFormat DEFAULT_AUDIO_FORMAT = new AudioFormat(16000, 16, 1, true, false);
/**
* The format in which audio files will be saved.
*/
public static final String FILE_FORMAT = "wav";
private final AudioFormat format; private final AudioFormat format;
private final DataLine.Info info; private final DataLine.Info info;
@ -78,7 +83,7 @@ public final class AudioRecorder {
line.start(); line.start();
// Prepare temp file // Prepare temp file
tempFile = Files.createTempFile("recording", "wav"); tempFile = Files.createTempFile("recording", FILE_FORMAT);
// Start the recording // Start the recording
final var ais = new AudioInputStream(line); final var ais = new AudioInputStream(line);
@ -117,6 +122,6 @@ public final class AudioRecorder {
line.close(); line.close();
try { try {
Files.deleteIfExists(tempFile); Files.deleteIfExists(tempFile);
} catch (IOException e) {} } catch (final IOException e) {}
} }
} }

View File

@ -8,6 +8,8 @@ import java.io.ByteArrayInputStream;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Random; import java.util.Random;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -240,9 +242,10 @@ public final class ChatScene implements Restorable {
this.client = client; this.client = client;
this.writeProxy = writeProxy; this.writeProxy = writeProxy;
MessageControl.setUser(localDB.getUser());
MessageControl.setSceneContext(sceneContext);
chatList.setItems(FXCollections.observableList(localDB.getChats())); chatList.setItems(FXCollections.observableList(localDB.getChats()));
contactLabel.setText(localDB.getUser().getName()); contactLabel.setText(localDB.getUser().getName());
MessageControl.setUser(localDB.getUser());
if (!client.isOnline()) updateInfoLabel("You are offline", "infoLabel-info"); if (!client.isOnline()) updateInfoLabel("You are offline", "infoLabel-info");
recorder = new AudioRecorder(); recorder = new AudioRecorder();
@ -334,7 +337,9 @@ public final class ChatScene implements Restorable {
}); });
recorder.start(); recorder.start();
} else { } else {
pendingAttachment = new Attachment(recorder.finish(), AttachmentType.VOICE); pendingAttachment = new Attachment(recorder.finish(), "Voice_recording_"
+ DateTimeFormatter.ofPattern("yyyy_MM_dd-HH_mm_ss").format(LocalDateTime.now()) + "." + AudioRecorder.FILE_FORMAT,
AttachmentType.VOICE);
recording = false; recording = false;
Platform.runLater(() -> { Platform.runLater(() -> {
voiceButton.setGraphic(new ImageView(IconUtil.loadIconThemeSensitive("microphone", DEFAULT_ICON_SIZE))); voiceButton.setGraphic(new ImageView(IconUtil.loadIconThemeSensitive("microphone", DEFAULT_ICON_SIZE)));
@ -385,7 +390,7 @@ public final class ChatScene implements Restorable {
// Create the pending attachment // Create the pending attachment
try { try {
final var fileBytes = Files.readAllBytes(file.toPath()); final var fileBytes = Files.readAllBytes(file.toPath());
pendingAttachment = new Attachment(fileBytes, type); pendingAttachment = new Attachment(fileBytes, file.getName(), type);
checkPostConditions(false); checkPostConditions(false);
// Setting the preview image as image of the attachmentView // Setting the preview image as image of the attachmentView
if (type == AttachmentType.PICTURE) if (type == AttachmentType.PICTURE)

View File

@ -2,7 +2,7 @@ package envoy.client.ui.listcell;
import java.awt.Toolkit; import java.awt.Toolkit;
import java.awt.datatransfer.StringSelection; import java.awt.datatransfer.StringSelection;
import java.io.ByteArrayInputStream; import java.io.*;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.Map; import java.util.Map;
@ -16,9 +16,11 @@ import javafx.scene.control.MenuItem;
import javafx.scene.image.Image; import javafx.scene.image.Image;
import javafx.scene.image.ImageView; import javafx.scene.image.ImageView;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import javafx.stage.FileChooser;
import envoy.client.ui.AudioControl; import envoy.client.ui.AudioControl;
import envoy.client.ui.IconUtil; import envoy.client.ui.IconUtil;
import envoy.client.ui.SceneContext;
import envoy.data.Message; import envoy.data.Message;
import envoy.data.Message.MessageStatus; import envoy.data.Message.MessageStatus;
import envoy.data.User; import envoy.data.User;
@ -38,6 +40,8 @@ public class MessageControl extends Label {
private static User client; private static User client;
private static SceneContext sceneContext;
private static final DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss") private static final DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss")
.withZone(ZoneId.systemDefault()); .withZone(ZoneId.systemDefault());
private static final Map<MessageStatus, Image> statusImages = IconUtil.loadByEnum(MessageStatus.class, 16); private static final Map<MessageStatus, Image> statusImages = IconUtil.loadByEnum(MessageStatus.class, 16);
@ -116,11 +120,31 @@ public class MessageControl extends Label {
private void loadMessageInfoScene(Message message) { logger.log(Level.FINEST, "message info scene was requested for " + message); } private void loadMessageInfoScene(Message message) { logger.log(Level.FINEST, "message info scene was requested for " + message); }
private void saveAttachment(Message message) { logger.log(Level.FINEST, "attachment saving was requested for " + message); } private void saveAttachment(Message message) {
// Show save file dialog
final var fileChooser = new FileChooser();
fileChooser.setInitialFileName(message.getAttachment().getName());
final File file = fileChooser.showSaveDialog(sceneContext.getStage());
// A file was selected
if (file != null) try (FileOutputStream fos = new FileOutputStream(file)) {
fos.write(message.getAttachment().getData());
logger.log(Level.FINE, "Attachment of " + message + " was saved.");
} catch (final IOException e) {
logger.log(Level.WARNING, "Could not save attachment of " + message + ": ", e);
}
}
/** /**
* @param client the user who has logged in * @param client the user who has logged in
* @since Envoy Client v0.1-beta * @since Envoy Client v0.1-beta
*/ */
public static void setUser(User client) { MessageControl.client = client; } public static void setUser(User client) { MessageControl.client = client; }
/**
* @param sceneContext the scene context storing the stage used in Envoy
* @since Envoy Client v0.1-beta
*/
public static void setSceneContext(SceneContext sceneContext) { MessageControl.sceneContext = sceneContext; }
} }

View File

@ -18,29 +18,28 @@ public class Attachment implements Serializable {
/** /**
* Defines the type of the attachment. * Defines the type of the attachment.
* *
* @since Envoy Common v0.1-beta * @since Envoy Common v0.1-beta
*/ */
public enum AttachmentType { public enum AttachmentType {
/** /**
* This attachment type denotes a picture. * This attachment type denotes a picture.
* *
* @since Envoy Common v0.1-beta * @since Envoy Common v0.1-beta
*/ */
PICTURE, PICTURE,
/** /**
* This attachment type denotes a video. * This attachment type denotes a video.
* *
* @since Envoy Common v0.1-beta * @since Envoy Common v0.1-beta
*/ */
VIDEO, VIDEO,
/** /**
* This attachment type denotes a voice message. * This attachment type denotes a voice message.
* *
* @since Envoy Common v0.1-beta * @since Envoy Common v0.1-beta
*/ */
VOICE, VOICE,
@ -55,19 +54,22 @@ public class Attachment implements Serializable {
private final byte[] data; private final byte[] data;
private final AttachmentType type; private final AttachmentType type;
private final String name;
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 2L;
/** /**
* Constructs an attachment. * Constructs an attachment.
* *
* @param data the data of the attachment * @param data the data of the attachment
* @param name the name of the attachment
* @param type the type of the attachment * @param type the type of the attachment
* @since Envoy Common v0.1-beta * @since Envoy Common v0.1-beta
*/ */
public Attachment(byte[] data, AttachmentType type) { public Attachment(byte[] data, String name, AttachmentType type) {
this.data = data; this.data = data;
this.type = type; this.type = type;
this.name = name;
} }
/** /**
@ -81,4 +83,10 @@ public class Attachment implements Serializable {
* @since Envoy Common v0.1-beta * @since Envoy Common v0.1-beta
*/ */
public AttachmentType getType() { return type; } public AttachmentType getType() { return type; }
/**
* @return the name
* @since Envoy Common v0.2-beta
*/
public String getName() { return name; }
} }

View File

@ -47,7 +47,7 @@ public class Message {
/** /**
* Named query retrieving pending messages for a user (parameter {@code :user}) * Named query retrieving pending messages for a user (parameter {@code :user})
* which was last seen after a specific date (parameter {@code :lastSeen}). * which was last seen after a specific date (parameter {@code :lastSeen}).
* *
* @since Envoy Server Standalone v0.1-beta * @since Envoy Server Standalone v0.1-beta
*/ */
public static final String getPending = "Message.getPending"; public static final String getPending = "Message.getPending";
@ -76,6 +76,7 @@ public class Message {
protected envoy.data.Message.MessageStatus status; protected envoy.data.Message.MessageStatus status;
protected AttachmentType attachmentType; protected AttachmentType attachmentType;
protected byte[] attachment; protected byte[] attachment;
protected String attachmentName;
protected boolean forwarded; protected boolean forwarded;
/** /**
@ -93,7 +94,7 @@ public class Message {
* @since Envoy Server Standalone v0.1-alpha * @since Envoy Server Standalone v0.1-alpha
*/ */
public Message(envoy.data.Message message) { public Message(envoy.data.Message message) {
PersistenceManager persistenceManager = PersistenceManager.getInstance(); final var persistenceManager = PersistenceManager.getInstance();
id = message.getID(); id = message.getID();
status = message.getStatus(); status = message.getStatus();
text = message.getText(); text = message.getText();
@ -104,8 +105,10 @@ public class Message {
recipient = persistenceManager.getContactByID(message.getRecipientID()); recipient = persistenceManager.getContactByID(message.getRecipientID());
forwarded = message.isForwarded(); forwarded = message.isForwarded();
if (message.hasAttachment()) { if (message.hasAttachment()) {
attachment = message.getAttachment().getData(); final var messageAttachment = message.getAttachment();
attachmentType = message.getAttachment().getType(); attachment = messageAttachment.getData();
attachmentName = messageAttachment.getName();
attachmentType = messageAttachment.getType();
} }
} }
@ -123,20 +126,20 @@ public class Message {
* @since Envoy Server Standalone v0.1-beta * @since Envoy Server Standalone v0.1-beta
*/ */
MessageBuilder prepareBuilder() { MessageBuilder prepareBuilder() {
var builder = new MessageBuilder(sender.getID(), recipient.getID(), id).setText(text) final var builder = new MessageBuilder(sender.getID(), recipient.getID(), id).setText(text)
.setCreationDate(creationDate) .setCreationDate(creationDate)
.setReceivedDate(receivedDate) .setReceivedDate(receivedDate)
.setReadDate(readDate) .setReadDate(readDate)
.setStatus(status) .setStatus(status)
.setForwarded(forwarded); .setForwarded(forwarded);
if (attachment != null) builder.setAttachment(new Attachment(attachment, attachmentType)); if (attachment != null) builder.setAttachment(new Attachment(attachment, attachmentName, attachmentType));
return builder; return builder;
} }
/** /**
* Sets the message status to {@link MessageStatus#RECEIVED} and sets the * Sets the message status to {@link MessageStatus#RECEIVED} and sets the
* current time stamp as the received date. * current time stamp as the received date.
* *
* @since Envoy Server Standalone v0.1-beta * @since Envoy Server Standalone v0.1-beta
*/ */
public void received() { public void received() {
@ -147,7 +150,7 @@ public class Message {
/** /**
* Sets the message status to {@link MessageStatus#READ} and sets the * Sets the message status to {@link MessageStatus#READ} and sets the
* current time stamp as the read date. * current time stamp as the read date.
* *
* @since Envoy Server Standalone v0.1-beta * @since Envoy Server Standalone v0.1-beta
*/ */
public void read() { public void read() {
@ -282,6 +285,18 @@ public class Message {
*/ */
public void setAttachmentType(AttachmentType attachmentType) { this.attachmentType = attachmentType; } public void setAttachmentType(AttachmentType attachmentType) { this.attachmentType = attachmentType; }
/**
* @return the attachmentName
* @since Envoy Server v0.2-beta
*/
public String getAttachmentName() { return attachmentName; }
/**
* @param attachmentName the attachmentName to set
* @since Envoy Server v0.2-beta
*/
public void setAttachmentName(String attachmentName) { this.attachmentName = attachmentName; }
/** /**
* @return whether this message is a forwarded message * @return whether this message is a forwarded message
* @since Envoy Server Standalone v0.1-alpha * @since Envoy Server Standalone v0.1-alpha