Performing handshake and online init in LoginDialog
This commit is contained in:
		| @@ -51,7 +51,7 @@ public class Receiver implements Runnable { | ||||
|  | ||||
| 				try (ObjectInputStream oin = new ObjectInputStream(new ByteArrayInputStream(objBytes))) { | ||||
| 					Object obj = oin.readObject(); | ||||
| 					logger.finest("Received object " + obj); | ||||
| 					logger.info("Received object " + obj); | ||||
|  | ||||
| 					// Get appropriate processor | ||||
| 					@SuppressWarnings("rawtypes") | ||||
|   | ||||
| @@ -2,17 +2,25 @@ package envoy.client.ui; | ||||
|  | ||||
| import java.awt.*; | ||||
| import java.awt.event.ItemEvent; | ||||
| import java.io.IOException; | ||||
| import java.security.NoSuchAlgorithmException; | ||||
| import java.util.Arrays; | ||||
| import java.util.logging.Logger; | ||||
|  | ||||
| import javax.naming.TimeLimitExceededException; | ||||
| import javax.swing.*; | ||||
| import javax.swing.border.EmptyBorder; | ||||
|  | ||||
| import envoy.client.data.Settings; | ||||
| import envoy.client.data.*; | ||||
| import envoy.client.event.HandshakeSuccessfulEvent; | ||||
| import envoy.client.net.Client; | ||||
| import envoy.client.util.EnvoyLog; | ||||
| import envoy.data.LoginCredentials; | ||||
| import envoy.data.Message; | ||||
| import envoy.data.User; | ||||
| import envoy.event.EventBus; | ||||
| import envoy.event.HandshakeRejectionEvent; | ||||
| import envoy.exception.EnvoyException; | ||||
|  | ||||
| /** | ||||
|  * Project: <strong>envoy-client</strong><br> | ||||
| @@ -25,7 +33,7 @@ import envoy.event.HandshakeRejectionEvent; | ||||
|  */ | ||||
| public class LoginDialog extends JDialog { | ||||
|  | ||||
| 	private final JPanel	contentPanel; | ||||
| 	private JPanel			contentPanel; | ||||
| 	private JTextField		textField; | ||||
| 	private JPasswordField	passwordField; | ||||
| 	private JPasswordField	repeatPasswordField; | ||||
| @@ -47,14 +55,111 @@ public class LoginDialog extends JDialog { | ||||
|  | ||||
| 	private LoginCredentials credentials; | ||||
|  | ||||
| 	private static final long serialVersionUID = 352021600833907468L; | ||||
| 	private final Client			client; | ||||
| 	private final LocalDb			localDb; | ||||
| 	private final Cache<Message>	receivedMessageCache; | ||||
|  | ||||
| 	private static final Config	config				= Config.getInstance(); | ||||
| 	private static final Logger	logger				= EnvoyLog.getLogger(LoginDialog.class.getSimpleName()); | ||||
| 	private static final long	serialVersionUID	= 352021600833907468L; | ||||
|  | ||||
| 	/** | ||||
| 	 * Displays a dialog enabling the user to enter their user name and password. | ||||
| 	 * | ||||
| 	 * @param client               the client used to perform the handshake | ||||
| 	 * @param localDb              the local database in which data is persisted | ||||
| 	 * @param receivedMessageCache the cache that stored messages received during | ||||
| 	 *                             the handshake | ||||
| 	 * @since Envoy v0.3-alpha | ||||
| 	 */ | ||||
| 	public LoginDialog() { | ||||
| 	public LoginDialog(Client client, LocalDb localDb, Cache<Message> receivedMessageCache) { | ||||
| 		this.client					= client; | ||||
| 		this.localDb				= localDb; | ||||
| 		this.receivedMessageCache	= receivedMessageCache; | ||||
|  | ||||
| 		// Prepare handshake | ||||
| 		localDb.loadIdGenerator(); | ||||
|  | ||||
| 		initUi(); | ||||
|  | ||||
| 		okButton.addActionListener((evt) -> { | ||||
| 			try { | ||||
| 				if (registerCheckBox.isSelected()) { | ||||
| 					// Check password equality | ||||
| 					if (Arrays.equals(passwordField.getPassword(), repeatPasswordField.getPassword())) | ||||
| 						credentials = new LoginCredentials(textField.getText(), passwordField.getPassword(), true); | ||||
| 					else { | ||||
| 						JOptionPane.showMessageDialog(this, "The repeated password is not the origional password!"); | ||||
| 						clearPasswordFields(); | ||||
| 					} | ||||
| 				} else credentials = new LoginCredentials(textField.getText(), passwordField.getPassword(), false); | ||||
| 				performHandshake(); | ||||
| 			} catch (NoSuchAlgorithmException e) { | ||||
| 				e.printStackTrace(); | ||||
| 			} | ||||
| 		}); | ||||
|  | ||||
| 		// Listen to handshake rejections | ||||
| 		EventBus.getInstance().register(HandshakeRejectionEvent.class, evt -> { | ||||
| 			for (Component c : contentPanel.getComponents()) | ||||
| 				if (c == errorMessage) contentPanel.remove(errorMessage); | ||||
| 			clearPasswordFields(); | ||||
| 			errorMessage			= new JLabel(evt.get()); | ||||
| 			gbc_errorMessage		= new GridBagConstraints(); | ||||
| 			gbc_errorMessage.gridx	= 2; | ||||
| 			gbc_errorMessage.gridy	= 0; | ||||
| 			gbc_errorMessage.fill	= GridBagConstraints.HORIZONTAL; | ||||
| 			gbc_errorMessage.insets	= new Insets(5, 5, 5, 5); | ||||
| 			contentPanel.add(errorMessage, gbc_errorMessage); | ||||
| 			contentPanel.revalidate(); | ||||
| 			contentPanel.repaint(); | ||||
| 		}); | ||||
|  | ||||
| 		// Exit the application when the dialog is cancelled | ||||
| 		cancelButton.addActionListener(evt -> { logger.info("The login process has been cancelled. Exiting..."); System.exit(0); }); | ||||
|  | ||||
| 		// Log in directly if configured | ||||
| 		if (config.hasLoginCredentials()) { | ||||
| 			credentials = config.getLoginCredentials(); | ||||
| 			performHandshake(); | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		setVisible(true); | ||||
| 	} | ||||
|  | ||||
| 	private void performHandshake() { | ||||
| 		try { | ||||
| 			client.performHandshake(credentials, receivedMessageCache); | ||||
| 			if (client.isOnline()) { | ||||
| 				client.initReceiver(localDb, receivedMessageCache); | ||||
| 				dispose(); | ||||
| 			} | ||||
| 		} catch (IOException | InterruptedException e) { | ||||
| 			e.printStackTrace(); | ||||
| 		} catch (TimeLimitExceededException e) { | ||||
| 			logger.warning("Could not connect to server. Trying offline mode..."); | ||||
| 			e.printStackTrace(); | ||||
| 			try { | ||||
| 				// Try entering offline mode | ||||
| 				localDb.loadUsers(); | ||||
| 				User clientUser = localDb.getUsers().get(credentials.getIdentifier()); | ||||
| 				if (clientUser == null) throw new EnvoyException("Could not enter offline mode: user name unknown"); | ||||
| 				client.setSender(clientUser); | ||||
| 				JOptionPane.showMessageDialog(null, | ||||
| 						"A connection to the server could not be established. Starting in offline mode.\n" + e, | ||||
| 						"Connection error", | ||||
| 						JOptionPane.WARNING_MESSAGE); | ||||
| 				dispose(); | ||||
| 			} catch (Exception e1) { | ||||
| 				JOptionPane.showMessageDialog(null, e1, "Client error", JOptionPane.ERROR_MESSAGE); | ||||
| 				System.exit(1); | ||||
| 				return; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	private void initUi() { | ||||
| 		setSize(338, 123); | ||||
| 		setLocationRelativeTo(null); | ||||
| 		getContentPane().setLayout(new BorderLayout()); | ||||
| @@ -67,150 +172,109 @@ public class LoginDialog extends JDialog { | ||||
| 		gbl_contentPanel.columnWeights	= new double[] { 0.0, 1.0, Double.MIN_VALUE }; | ||||
| 		gbl_contentPanel.rowWeights		= new double[] { 0.0, 0.0, Double.MIN_VALUE }; | ||||
| 		contentPanel.setLayout(gbl_contentPanel); | ||||
| 		{ | ||||
| 			lblUserName = new JLabel("Username:"); | ||||
| 			GridBagConstraints gbc_lblUserName = new GridBagConstraints(); | ||||
| 			gbc_lblUserName.anchor	= GridBagConstraints.EAST; | ||||
| 			gbc_lblUserName.insets	= new Insets(0, 0, 5, 5); | ||||
| 			gbc_lblUserName.gridx	= 0; | ||||
| 			gbc_lblUserName.gridy	= 0; | ||||
| 			contentPanel.add(lblUserName, gbc_lblUserName); | ||||
| 		} | ||||
| 		{ | ||||
| 			textField = new JTextField(); | ||||
| 			textField.setBorder(null); | ||||
| 			GridBagConstraints gbc_textField = new GridBagConstraints(); | ||||
| 			gbc_textField.insets	= new Insets(0, 0, 5, 0); | ||||
| 			gbc_textField.fill		= GridBagConstraints.HORIZONTAL; | ||||
| 			gbc_textField.gridx		= 1; | ||||
| 			gbc_textField.gridy		= 0; | ||||
| 			contentPanel.add(textField, gbc_textField); | ||||
| 			textField.setColumns(10); | ||||
| 		} | ||||
| 		{ | ||||
| 			lblPassword = new JLabel("Password:"); | ||||
| 			GridBagConstraints gbc_lblPassword = new GridBagConstraints(); | ||||
| 			gbc_lblPassword.anchor	= GridBagConstraints.EAST; | ||||
| 			gbc_lblPassword.insets	= new Insets(0, 0, 0, 5); | ||||
| 			gbc_lblPassword.gridx	= 0; | ||||
| 			gbc_lblPassword.gridy	= 1; | ||||
| 			contentPanel.add(lblPassword, gbc_lblPassword); | ||||
| 		} | ||||
| 		{ | ||||
| 			passwordField = new JPasswordField(); | ||||
| 			passwordField.setBorder(null); | ||||
| 			GridBagConstraints gbc_passwordField = new GridBagConstraints(); | ||||
| 			gbc_passwordField.fill	= GridBagConstraints.HORIZONTAL; | ||||
| 			gbc_passwordField.gridx	= 1; | ||||
| 			gbc_passwordField.gridy	= 1; | ||||
| 			contentPanel.add(passwordField, gbc_passwordField); | ||||
| 		} | ||||
| 		{ | ||||
| 			lblRepeatPassword				= new JLabel("Repeat Password:"); | ||||
| 			gbc_lblRepeatPassword			= new GridBagConstraints(); | ||||
| 			gbc_lblRepeatPassword.anchor	= GridBagConstraints.EAST; | ||||
| 			gbc_lblRepeatPassword.insets	= new Insets(0, 0, 0, 5); | ||||
| 			gbc_lblRepeatPassword.gridx		= 0; | ||||
| 			gbc_lblRepeatPassword.gridy		= 2; | ||||
| 		} | ||||
| 		{ | ||||
| 			repeatPasswordField				= new JPasswordField(); | ||||
| 			gbc_repeatPasswordField			= new GridBagConstraints(); | ||||
| 			gbc_repeatPasswordField.fill	= GridBagConstraints.HORIZONTAL; | ||||
| 			gbc_repeatPasswordField.gridx	= 1; | ||||
| 			gbc_repeatPasswordField.gridy	= 2; | ||||
| 		} | ||||
| 		{ | ||||
| 			EventBus.getInstance().register(HandshakeRejectionEvent.class, evt -> { | ||||
| 				contentPanel.remove(errorMessage); | ||||
| 				clearPasswordFields(); | ||||
| 				// TODO delete - only for testing purposes | ||||
| 				System.out.println("Caught HandshakeRejectionEvent with reason" + evt.get()); | ||||
| 				errorMessage			= new JLabel(evt.get()); | ||||
| 				gbc_errorMessage		= new GridBagConstraints(); | ||||
| 				gbc_errorMessage.gridx	= 2; | ||||
| 				gbc_errorMessage.gridy	= 0; | ||||
| 				gbc_errorMessage.fill	= GridBagConstraints.HORIZONTAL; | ||||
| 				gbc_errorMessage.insets	= new Insets(5, 5, 5, 5); | ||||
| 				contentPanel.add(errorMessage, gbc_errorMessage); | ||||
| 			}); | ||||
| 		} | ||||
| 		{ | ||||
| 			buttonPane = new JPanel(); | ||||
|  | ||||
| 			registerText = new JTextPane(); | ||||
| 			registerText.setEditable(false); | ||||
| 			registerText.setText("Register?"); | ||||
| 			registerText.setFont(new Font("Arial", Font.BOLD, 12)); | ||||
| 			registerText.setAlignmentX(LEFT_ALIGNMENT); | ||||
| 			buttonPane.add(registerText); | ||||
| 		lblUserName = new JLabel("Username:"); | ||||
| 		GridBagConstraints gbc_lblUserName = new GridBagConstraints(); | ||||
| 		gbc_lblUserName.anchor	= GridBagConstraints.EAST; | ||||
| 		gbc_lblUserName.insets	= new Insets(0, 0, 5, 5); | ||||
| 		gbc_lblUserName.gridx	= 0; | ||||
| 		gbc_lblUserName.gridy	= 0; | ||||
| 		contentPanel.add(lblUserName, gbc_lblUserName); | ||||
|  | ||||
| 			registerCheckBox = new JCheckBox(); | ||||
| 			registerCheckBox.setAlignmentX(LEFT_ALIGNMENT); | ||||
| 			registerCheckBox.addItemListener(e -> { | ||||
| 				switch (e.getStateChange()) { | ||||
| 					case ItemEvent.SELECTED: | ||||
| 						contentPanel.add(lblRepeatPassword, gbc_lblRepeatPassword); | ||||
| 						contentPanel.add(repeatPasswordField, gbc_repeatPasswordField); | ||||
| 						setSize(338, 148); | ||||
| 						break; | ||||
| 		textField = new JTextField(); | ||||
| 		textField.setBorder(null); | ||||
| 		GridBagConstraints gbc_textField = new GridBagConstraints(); | ||||
| 		gbc_textField.insets	= new Insets(0, 0, 5, 0); | ||||
| 		gbc_textField.fill		= GridBagConstraints.HORIZONTAL; | ||||
| 		gbc_textField.gridx		= 1; | ||||
| 		gbc_textField.gridy		= 0; | ||||
| 		contentPanel.add(textField, gbc_textField); | ||||
| 		textField.setColumns(10); | ||||
|  | ||||
| 					case ItemEvent.DESELECTED: | ||||
| 						if (repeatPasswordField.getParent() == contentPanel) { | ||||
| 							contentPanel.remove(lblRepeatPassword); | ||||
| 							contentPanel.remove(repeatPasswordField); | ||||
| 							setSize(338, 123); | ||||
| 						} | ||||
| 						break; | ||||
| 				} | ||||
| 				contentPanel.revalidate(); | ||||
| 				contentPanel.repaint(); | ||||
| 			}); | ||||
| 			buttonPane.add(registerCheckBox); | ||||
| 		lblPassword = new JLabel("Password:"); | ||||
| 		GridBagConstraints gbc_lblPassword = new GridBagConstraints(); | ||||
| 		gbc_lblPassword.anchor	= GridBagConstraints.EAST; | ||||
| 		gbc_lblPassword.insets	= new Insets(0, 0, 0, 5); | ||||
| 		gbc_lblPassword.gridx	= 0; | ||||
| 		gbc_lblPassword.gridy	= 1; | ||||
| 		contentPanel.add(lblPassword, gbc_lblPassword); | ||||
|  | ||||
| 			buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT)); | ||||
| 			getContentPane().add(buttonPane, BorderLayout.SOUTH); | ||||
| 			{ | ||||
| 				okButton = new PrimaryButton("OK"); | ||||
| 				okButton.addActionListener((evt) -> { | ||||
| 					try { | ||||
| 						if (registerCheckBox.isSelected()) { | ||||
| 							// password checking | ||||
| 							if (Arrays.equals(passwordField.getPassword(), repeatPasswordField.getPassword())) | ||||
| 								credentials = new LoginCredentials(textField.getText(), passwordField.getPassword(), true); | ||||
| 							else { | ||||
| 								JOptionPane.showMessageDialog(this, "The repeated password is not the origional password!"); | ||||
| 								clearPasswordFields(); | ||||
| 							} | ||||
| 						} else credentials = new LoginCredentials(textField.getText(), passwordField.getPassword(), false); | ||||
| 					} catch (NoSuchAlgorithmException e) { | ||||
| 						e.printStackTrace(); | ||||
| 		passwordField = new JPasswordField(); | ||||
| 		passwordField.setBorder(null); | ||||
| 		GridBagConstraints gbc_passwordField = new GridBagConstraints(); | ||||
| 		gbc_passwordField.fill	= GridBagConstraints.HORIZONTAL; | ||||
| 		gbc_passwordField.gridx	= 1; | ||||
| 		gbc_passwordField.gridy	= 1; | ||||
| 		contentPanel.add(passwordField, gbc_passwordField); | ||||
|  | ||||
| 		lblRepeatPassword				= new JLabel("Repeat Password:"); | ||||
| 		gbc_lblRepeatPassword			= new GridBagConstraints(); | ||||
| 		gbc_lblRepeatPassword.anchor	= GridBagConstraints.EAST; | ||||
| 		gbc_lblRepeatPassword.insets	= new Insets(0, 0, 0, 5); | ||||
| 		gbc_lblRepeatPassword.gridx		= 0; | ||||
| 		gbc_lblRepeatPassword.gridy		= 2; | ||||
|  | ||||
| 		repeatPasswordField				= new JPasswordField(); | ||||
| 		gbc_repeatPasswordField			= new GridBagConstraints(); | ||||
| 		gbc_repeatPasswordField.fill	= GridBagConstraints.HORIZONTAL; | ||||
| 		gbc_repeatPasswordField.gridx	= 1; | ||||
| 		gbc_repeatPasswordField.gridy	= 2; | ||||
|  | ||||
| 		buttonPane = new JPanel(); | ||||
|  | ||||
| 		registerText = new JTextPane(); | ||||
| 		registerText.setEditable(false); | ||||
| 		registerText.setText("Register?"); | ||||
| 		registerText.setFont(new Font("Arial", Font.BOLD, 12)); | ||||
| 		registerText.setAlignmentX(LEFT_ALIGNMENT); | ||||
| 		buttonPane.add(registerText); | ||||
|  | ||||
| 		registerCheckBox = new JCheckBox(); | ||||
| 		registerCheckBox.setAlignmentX(LEFT_ALIGNMENT); | ||||
| 		registerCheckBox.addItemListener(e -> { | ||||
| 			switch (e.getStateChange()) { | ||||
| 				case ItemEvent.SELECTED: | ||||
| 					contentPanel.add(lblRepeatPassword, gbc_lblRepeatPassword); | ||||
| 					contentPanel.add(repeatPasswordField, gbc_repeatPasswordField); | ||||
| 					setSize(338, 148); | ||||
| 					break; | ||||
|  | ||||
| 				case ItemEvent.DESELECTED: | ||||
| 					if (repeatPasswordField.getParent() == contentPanel) { | ||||
| 						contentPanel.remove(lblRepeatPassword); | ||||
| 						contentPanel.remove(repeatPasswordField); | ||||
| 						setSize(338, 123); | ||||
| 					} | ||||
| 				}); | ||||
| 				okButton.setActionCommand("OK"); | ||||
| 				buttonPane.add(okButton); | ||||
| 				getRootPane().setDefaultButton(okButton); | ||||
| 					break; | ||||
| 			} | ||||
| 			{ | ||||
| 				cancelButton = new PrimaryButton("Cancel"); | ||||
| 				cancelButton.addActionListener((evt) -> dispose()); | ||||
| 				cancelButton.setActionCommand("Cancel"); | ||||
| 				buttonPane.add(cancelButton); | ||||
| 			} | ||||
| 		} | ||||
| 			contentPanel.revalidate(); | ||||
| 			contentPanel.repaint(); | ||||
| 		}); | ||||
| 		buttonPane.add(registerCheckBox); | ||||
|  | ||||
| 		buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT)); | ||||
| 		getContentPane().add(buttonPane, BorderLayout.SOUTH); | ||||
| 		okButton = new PrimaryButton("OK"); | ||||
| 		okButton.setActionCommand("OK"); | ||||
| 		buttonPane.add(okButton); | ||||
| 		getRootPane().setDefaultButton(okButton); | ||||
|  | ||||
| 		cancelButton = new PrimaryButton("Cancel"); | ||||
| 		cancelButton.setActionCommand("Cancel"); | ||||
| 		buttonPane.add(cancelButton); | ||||
| 		setTheme(); | ||||
|  | ||||
| 		setModal(true); | ||||
| 		setVisible(true); | ||||
| 		setModalityType(Dialog.DEFAULT_MODALITY_TYPE); | ||||
|  | ||||
| 		EventBus.getInstance().register(HandshakeSuccessfulEvent.class, evt -> dispose()); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Resets the text stored in the passwort fields. | ||||
| 	 * Resets the text stored in the password fields. | ||||
| 	 * | ||||
| 	 * @since Envoy v0.3-alpha | ||||
| 	 */ | ||||
| 	public void clearPasswordFields() { | ||||
| 	private void clearPasswordFields() { | ||||
| 		passwordField.setText(null); | ||||
| 		repeatPasswordField.setText(null); | ||||
| 	} | ||||
| @@ -258,11 +322,4 @@ public class LoginDialog extends JDialog { | ||||
| 		cancelButton.setBackground(theme.getInteractableBackgroundColor()); | ||||
| 		cancelButton.setForeground(theme.getInteractableForegroundColor()); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @return the {@link LoginCredentials} entered by the user, or {@code null} if | ||||
| 	 *         the dialog has been cancelled | ||||
| 	 * @since Envoy v0.3-alpha | ||||
| 	 */ | ||||
| 	public LoginCredentials getCredentials() { return credentials; } | ||||
| } | ||||
| @@ -15,9 +15,7 @@ import envoy.client.data.*; | ||||
| import envoy.client.net.Client; | ||||
| import envoy.client.net.WriteProxy; | ||||
| import envoy.client.util.EnvoyLog; | ||||
| import envoy.data.LoginCredentials; | ||||
| import envoy.data.Message; | ||||
| import envoy.data.User; | ||||
| import envoy.exception.EnvoyException; | ||||
|  | ||||
| /** | ||||
| @@ -74,14 +72,6 @@ public class Startup { | ||||
| 		EnvoyLog.setFileLevelBarrier(config.getFileLevelBarrier()); | ||||
| 		EnvoyLog.setConsoleLevelBarrier(config.getConsoleLevelBarrier()); | ||||
|  | ||||
| 		// Acquire login credentials | ||||
| 		LoginCredentials credentials = config.hasLoginCredentials() ? config.getLoginCredentials() : new LoginDialog().getCredentials(); | ||||
|  | ||||
| 		if (credentials == null) { | ||||
| 			logger.info("The login process has been cancelled. Exiting..."); | ||||
| 			System.exit(0); | ||||
| 		} | ||||
|  | ||||
| 		// Initialize the local database | ||||
| 		LocalDb localDb; | ||||
| 		if (config.isIgnoreLocalDB()) { | ||||
| @@ -95,45 +85,23 @@ public class Startup { | ||||
| 		} catch (IOException e3) { | ||||
| 			logger.log(Level.SEVERE, "Could not initialize local database", e3); | ||||
| 			JOptionPane | ||||
| 				.showMessageDialog(null, "Could not initialize local database!\n" + e3.toString(), "Local database error", JOptionPane.ERROR_MESSAGE); | ||||
| 				.showMessageDialog(null, "Could not initialize local database!\n" + e3, "Local database error", JOptionPane.ERROR_MESSAGE); | ||||
| 			System.exit(1); | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		SwingUtilities.invokeLater(() -> chatWindow.setVisible(true)); | ||||
|  | ||||
| 		// Acquire the client user (with ID) either from the server or from the local | ||||
| 		// database, which triggers offline mode | ||||
| 		// Initialize client and unread message cache | ||||
| 		Client			client	= new Client(); | ||||
| 		Cache<Message>	cache	= new Cache<>(); | ||||
| 		try { | ||||
| 			// Try entering online mode first | ||||
| 			localDb.loadIdGenerator(); | ||||
| 			client.performHandshake(credentials, cache); | ||||
| 			client.initReceiver(localDb, cache); | ||||
| 		} catch (Exception e1) { | ||||
| 			logger.warning("Could not connect to server. Trying offline mode..."); | ||||
| 			e1.printStackTrace(); | ||||
| 			try { | ||||
| 				// Try entering offline mode | ||||
| 				localDb.loadUsers(); | ||||
| 				User clientUser = localDb.getUsers().get(credentials.getIdentifier()); | ||||
| 				if (clientUser == null) throw new EnvoyException("Could not enter offline mode: user name unknown"); | ||||
| 				client.setSender(clientUser); | ||||
| 				JOptionPane.showMessageDialog(null, | ||||
| 						"A connection to the server could not be established. Starting in offline mode.\n" + e1, | ||||
| 						"Connection error", | ||||
| 						JOptionPane.WARNING_MESSAGE); | ||||
| 			} catch (Exception e2) { | ||||
| 				JOptionPane.showMessageDialog(null, e2.toString(), "Client error", JOptionPane.ERROR_MESSAGE); | ||||
| 				System.exit(1); | ||||
| 				return; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		// Try to connect to the server | ||||
| 		new LoginDialog(client, localDb, cache); | ||||
| 		SwingUtilities.invokeLater(() -> chatWindow.setVisible(true)); | ||||
|  | ||||
| 		// Set client user in local database | ||||
| 		localDb.setUser(client.getSender()); | ||||
|  | ||||
|  | ||||
| 		// Initialize chats in local database | ||||
| 		try { | ||||
| 			localDb.initializeUserStorage(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user