Added image preview when an image is used as attachment
additionally: - added search icons - solved problem of Scrollbars being shown too far from the right side (all praise FX, Swing did not offer such a simple solution) - relocated infoLabel into the highest row, is now located above the messageList
This commit is contained in:
		@@ -2,6 +2,7 @@ package envoy.client.ui.controller;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
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.File;
 | 
					import java.io.File;
 | 
				
			||||||
import java.io.IOException;
 | 
					import java.io.IOException;
 | 
				
			||||||
import java.nio.file.Files;
 | 
					import java.nio.file.Files;
 | 
				
			||||||
@@ -14,6 +15,7 @@ import javafx.collections.FXCollections;
 | 
				
			|||||||
import javafx.fxml.FXML;
 | 
					import javafx.fxml.FXML;
 | 
				
			||||||
import javafx.scene.control.*;
 | 
					import javafx.scene.control.*;
 | 
				
			||||||
import javafx.scene.control.Alert.AlertType;
 | 
					import javafx.scene.control.Alert.AlertType;
 | 
				
			||||||
 | 
					import javafx.scene.image.Image;
 | 
				
			||||||
import javafx.scene.image.ImageView;
 | 
					import javafx.scene.image.ImageView;
 | 
				
			||||||
import javafx.scene.input.KeyCode;
 | 
					import javafx.scene.input.KeyCode;
 | 
				
			||||||
import javafx.scene.input.KeyEvent;
 | 
					import javafx.scene.input.KeyEvent;
 | 
				
			||||||
@@ -98,6 +100,8 @@ public final class ChatScene implements Restorable {
 | 
				
			|||||||
	private static final Settings	settings	= Settings.getInstance();
 | 
						private static final Settings	settings	= Settings.getInstance();
 | 
				
			||||||
	private static final EventBus	eventBus	= EventBus.getInstance();
 | 
						private static final EventBus	eventBus	= EventBus.getInstance();
 | 
				
			||||||
	private static final Logger		logger		= EnvoyLog.getLogger(ChatScene.class);
 | 
						private static final Logger		logger		= EnvoyLog.getLogger(ChatScene.class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private static final Image	DEFAULT_ATTACHMENT_VIEW_IMAGE	= IconUtil.loadIconThemeSensitive("attachment_present", 20);
 | 
				
			||||||
	private static final int	MAX_MESSAGE_LENGTH				= 255;
 | 
						private static final int	MAX_MESSAGE_LENGTH				= 255;
 | 
				
			||||||
	private static final int	DEFAULT_ICON_SIZE				= 16;
 | 
						private static final int	DEFAULT_ICON_SIZE				= 16;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -116,7 +120,7 @@ public final class ChatScene implements Restorable {
 | 
				
			|||||||
		settingsButton.setGraphic(new ImageView(IconUtil.loadIconThemeSensitive("settings", DEFAULT_ICON_SIZE)));
 | 
							settingsButton.setGraphic(new ImageView(IconUtil.loadIconThemeSensitive("settings", DEFAULT_ICON_SIZE)));
 | 
				
			||||||
		voiceButton.setGraphic(new ImageView(IconUtil.loadIconThemeSensitive("microphone", DEFAULT_ICON_SIZE)));
 | 
							voiceButton.setGraphic(new ImageView(IconUtil.loadIconThemeSensitive("microphone", DEFAULT_ICON_SIZE)));
 | 
				
			||||||
		attachmentButton.setGraphic(new ImageView(IconUtil.loadIconThemeSensitive("attachment", DEFAULT_ICON_SIZE)));
 | 
							attachmentButton.setGraphic(new ImageView(IconUtil.loadIconThemeSensitive("attachment", DEFAULT_ICON_SIZE)));
 | 
				
			||||||
		attachmentView.setImage(IconUtil.loadIconThemeSensitive("attachment_present", 20));
 | 
							attachmentView.setImage(DEFAULT_ATTACHMENT_VIEW_IMAGE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Listen to received messages
 | 
							// Listen to received messages
 | 
				
			||||||
		eventBus.register(MessageCreationEvent.class, e -> {
 | 
							eventBus.register(MessageCreationEvent.class, e -> {
 | 
				
			||||||
@@ -235,7 +239,7 @@ public final class ChatScene implements Restorable {
 | 
				
			|||||||
				recording = false;
 | 
									recording = false;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			pendingAttachment = null;
 | 
								pendingAttachment = null;
 | 
				
			||||||
			attachmentView.setVisible(false);
 | 
								updateAttachmentView(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			remainingChars.setVisible(true);
 | 
								remainingChars.setVisible(true);
 | 
				
			||||||
			remainingChars
 | 
								remainingChars
 | 
				
			||||||
@@ -286,7 +290,7 @@ public final class ChatScene implements Restorable {
 | 
				
			|||||||
						voiceButton.setGraphic(new ImageView(IconUtil.loadIconThemeSensitive("microphone", DEFAULT_ICON_SIZE)));
 | 
											voiceButton.setGraphic(new ImageView(IconUtil.loadIconThemeSensitive("microphone", DEFAULT_ICON_SIZE)));
 | 
				
			||||||
						voiceButton.setText(null);
 | 
											voiceButton.setText(null);
 | 
				
			||||||
						checkPostConditions(false);
 | 
											checkPostConditions(false);
 | 
				
			||||||
						attachmentView.setVisible(true);
 | 
											updateAttachmentView(true);
 | 
				
			||||||
					});
 | 
										});
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			} catch (final EnvoyException e) {
 | 
								} catch (final EnvoyException e) {
 | 
				
			||||||
@@ -330,7 +334,11 @@ public final class ChatScene implements Restorable {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			// Create the pending attachment
 | 
								// Create the pending attachment
 | 
				
			||||||
			try {
 | 
								try {
 | 
				
			||||||
				pendingAttachment = new Attachment(Files.readAllBytes(file.toPath()), type);
 | 
									final var fileBytes = Files.readAllBytes(file.toPath());
 | 
				
			||||||
 | 
									pendingAttachment = new Attachment(fileBytes, type);
 | 
				
			||||||
 | 
									// Setting the preview image as image of the attachmentView
 | 
				
			||||||
 | 
									if (type == AttachmentType.PICTURE)
 | 
				
			||||||
 | 
										attachmentView.setImage(new Image(new ByteArrayInputStream(fileBytes), DEFAULT_ICON_SIZE, DEFAULT_ICON_SIZE, true, true));
 | 
				
			||||||
				attachmentView.setVisible(true);
 | 
									attachmentView.setVisible(true);
 | 
				
			||||||
			} catch (final IOException e) {
 | 
								} catch (final IOException e) {
 | 
				
			||||||
				new Alert(AlertType.ERROR, "The selected file could not be loaded!").showAndWait();
 | 
									new Alert(AlertType.ERROR, "The selected file could not be loaded!").showAndWait();
 | 
				
			||||||
@@ -430,7 +438,7 @@ public final class ChatScene implements Restorable {
 | 
				
			|||||||
			if (pendingAttachment != null) {
 | 
								if (pendingAttachment != null) {
 | 
				
			||||||
				builder.setAttachment(pendingAttachment);
 | 
									builder.setAttachment(pendingAttachment);
 | 
				
			||||||
				pendingAttachment = null;
 | 
									pendingAttachment = null;
 | 
				
			||||||
				attachmentView.setVisible(false);
 | 
									updateAttachmentView(false);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			// Building the final message
 | 
								// Building the final message
 | 
				
			||||||
			final var message = currentChat.getRecipient() instanceof Group ? builder.buildGroupMessage((Group) currentChat.getRecipient())
 | 
								final var message = currentChat.getRecipient() instanceof Group ? builder.buildGroupMessage((Group) currentChat.getRecipient())
 | 
				
			||||||
@@ -479,6 +487,20 @@ public final class ChatScene implements Restorable {
 | 
				
			|||||||
		infoLabel.setVisible(true);
 | 
							infoLabel.setVisible(true);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Updates he {@code attachmentView} in terms of visibility.<br>
 | 
				
			||||||
 | 
						 * Additionally resets the shown image to
 | 
				
			||||||
 | 
						 * {@code DEFAULT_ATTACHMENT_VIEW_IMAGE} if another image is currently
 | 
				
			||||||
 | 
						 * present.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * @param visible whether the {@code attachmentView} should be displayed
 | 
				
			||||||
 | 
						 * @since Envoy Client v0.1-beta
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						private void updateAttachmentView(boolean visible) {
 | 
				
			||||||
 | 
							if (!attachmentView.getImage().equals(DEFAULT_ATTACHMENT_VIEW_IMAGE)) attachmentView.setImage(DEFAULT_ATTACHMENT_VIEW_IMAGE);
 | 
				
			||||||
 | 
							attachmentView.setVisible(visible);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Context menu actions
 | 
						// Context menu actions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@FXML
 | 
						@FXML
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -51,7 +51,7 @@
 | 
				
			|||||||
				<Insets bottom="5.0" left="10.0" />
 | 
									<Insets bottom="5.0" left="10.0" />
 | 
				
			||||||
			</GridPane.margin>
 | 
								</GridPane.margin>
 | 
				
			||||||
			<padding>
 | 
								<padding>
 | 
				
			||||||
				<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
 | 
									<Insets bottom="5.0" left="5.0" right="2.0" top="5.0" />
 | 
				
			||||||
			</padding>
 | 
								</padding>
 | 
				
			||||||
			<contextMenu>
 | 
								<contextMenu>
 | 
				
			||||||
				<ContextMenu anchorLocation="CONTENT_TOP_LEFT">
 | 
									<ContextMenu anchorLocation="CONTENT_TOP_LEFT">
 | 
				
			||||||
@@ -82,18 +82,17 @@
 | 
				
			|||||||
				<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
 | 
									<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
 | 
				
			||||||
			</padding>
 | 
								</padding>
 | 
				
			||||||
		</Button>
 | 
							</Button>
 | 
				
			||||||
		<ListView fx:id="messageList" prefHeight="257.0"
 | 
							<ListView fx:id="messageList" GridPane.columnIndex="1"
 | 
				
			||||||
			prefWidth="465.0" GridPane.columnIndex="1"
 | 
					 | 
				
			||||||
			GridPane.columnSpan="2147483647" GridPane.rowIndex="1"
 | 
								GridPane.columnSpan="2147483647" GridPane.rowIndex="1"
 | 
				
			||||||
			GridPane.rowSpan="2">
 | 
								GridPane.rowSpan="2">
 | 
				
			||||||
			<GridPane.margin>
 | 
								<GridPane.margin>
 | 
				
			||||||
				<Insets left="5.0" right="10.0" />
 | 
									<Insets left="5.0" right="10.0" />
 | 
				
			||||||
			</GridPane.margin>
 | 
								</GridPane.margin>
 | 
				
			||||||
			<padding>
 | 
								<padding>
 | 
				
			||||||
				<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
 | 
									<Insets bottom="5.0" left="5.0" right="2.0" top="5.0" />
 | 
				
			||||||
			</padding>
 | 
								</padding>
 | 
				
			||||||
		</ListView>
 | 
							</ListView>
 | 
				
			||||||
		<ButtonBar prefWidth="436.0" GridPane.columnIndex="1"
 | 
							<ButtonBar buttonMinWidth="40.0" GridPane.columnIndex="1"
 | 
				
			||||||
			GridPane.columnSpan="2147483647" GridPane.halignment="CENTER"
 | 
								GridPane.columnSpan="2147483647" GridPane.halignment="CENTER"
 | 
				
			||||||
			GridPane.rowIndex="5" GridPane.valignment="BOTTOM">
 | 
								GridPane.rowIndex="5" GridPane.valignment="BOTTOM">
 | 
				
			||||||
			<GridPane.margin>
 | 
								<GridPane.margin>
 | 
				
			||||||
@@ -101,7 +100,11 @@
 | 
				
			|||||||
			</GridPane.margin>
 | 
								</GridPane.margin>
 | 
				
			||||||
			<buttons>
 | 
								<buttons>
 | 
				
			||||||
				<Button fx:id="attachmentButton" disable="true"
 | 
									<Button fx:id="attachmentButton" disable="true"
 | 
				
			||||||
					mnemonicParsing="false" onAction="#attachmentButtonClicked" />
 | 
										mnemonicParsing="false" onAction="#attachmentButtonClicked">
 | 
				
			||||||
 | 
										<padding>
 | 
				
			||||||
 | 
											<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
 | 
				
			||||||
 | 
										</padding>
 | 
				
			||||||
 | 
									</Button>
 | 
				
			||||||
				<Button fx:id="voiceButton" disable="true"
 | 
									<Button fx:id="voiceButton" disable="true"
 | 
				
			||||||
					onAction="#voiceButtonClicked">
 | 
										onAction="#voiceButtonClicked">
 | 
				
			||||||
					<padding>
 | 
										<padding>
 | 
				
			||||||
@@ -177,7 +180,7 @@
 | 
				
			|||||||
		</Label>
 | 
							</Label>
 | 
				
			||||||
		<Label fx:id="infoLabel" text="Something happened"
 | 
							<Label fx:id="infoLabel" text="Something happened"
 | 
				
			||||||
			textFill="#faa007" visible="false" wrapText="true"
 | 
								textFill="#faa007" visible="false" wrapText="true"
 | 
				
			||||||
			GridPane.columnIndex="1" GridPane.rowIndex="1">
 | 
								GridPane.columnIndex="1">
 | 
				
			||||||
			<GridPane.margin>
 | 
								<GridPane.margin>
 | 
				
			||||||
				<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
 | 
									<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
 | 
				
			||||||
			</GridPane.margin>
 | 
								</GridPane.margin>
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										
											BIN
										
									
								
								src/main/resources/icons/dark/search.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/main/resources/icons/dark/search.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 10 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/main/resources/icons/light/search.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/main/resources/icons/light/search.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 8.3 KiB  | 
		Reference in New Issue
	
	Block a user