2020-10-02 15:23:21 +02:00
package envoy.client.ui.chatscene ;
import java.util.Random ;
import java.util.function.* ;
import java.util.logging.Level ;
2020-10-08 17:09:09 +02:00
import javafx.scene.control.* ;
import javafx.scene.control.Alert.AlertType ;
2020-10-02 15:23:21 +02:00
import javafx.scene.control.skin.VirtualFlow ;
import envoy.client.data.Context ;
import envoy.client.data.commands.* ;
import envoy.client.helper.ShutdownHelper ;
import envoy.client.ui.SceneContext.SceneInfo ;
import envoy.client.ui.controller.ChatScene ;
2020-10-08 16:12:24 +02:00
import envoy.client.util.* ;
2020-10-02 15:23:21 +02:00
import envoy.data.Message ;
2020-10-08 17:09:09 +02:00
import envoy.data.User.UserStatus ;
2020-10-02 15:23:21 +02:00
import envoy.util.EnvoyLog ;
/ * *
* Contains all { @link SystemCommand } s used for
* { @link envoy . client . ui . controller . ChatScene } .
*
* @author Leon Hofmeister
* @since Envoy Client v0 . 3 - beta
* /
public final class ChatSceneCommands {
private final ListView < Message > messageList ;
private final SystemCommandMap messageTextAreaCommands = new SystemCommandMap ( ) ;
private final SystemCommandBuilder builder = new SystemCommandBuilder ( messageTextAreaCommands ) ;
private static final String messageDependantCommandDescription = " the given message. Use s/S to use the selected message. Otherwise expects a number relative to the uppermost completely visible message. " ;
/ * *
*
* @param messageList the message list to use for some commands
* @param chatScene the instance of { @code ChatScene } that uses this object
* @since Envoy Client v0 . 3 - beta
* /
public ChatSceneCommands ( ListView < Message > messageList , ChatScene chatScene ) {
this . messageList = messageList ;
2020-10-06 22:20:11 +02:00
// Error message initialization
builder . setAction ( text - > { throw new RuntimeException ( ) ; } ) . setDescription ( " Shows an error message. " ) . buildNoArg ( " error " ) ;
2020-10-02 15:23:21 +02:00
// Do A Barrel roll initialization
final var random = new Random ( ) ;
builder . setAction ( text - > chatScene . doABarrelRoll ( Integer . parseInt ( text . get ( 0 ) ) , Double . parseDouble ( text . get ( 1 ) ) ) )
. setDefaults ( Integer . toString ( random . nextInt ( 3 ) + 1 ) , Double . toString ( random . nextDouble ( ) * 3 + 1 ) )
. setDescription ( " See for yourself :) " )
. setNumberOfArguments ( 2 )
. build ( " dabr " ) ;
// Logout initialization
2020-10-08 16:12:24 +02:00
builder . setAction ( text - > UserUtil . logout ( ) ) . setDescription ( " Logs you out. " ) . buildNoArg ( " logout " ) ;
2020-10-02 15:23:21 +02:00
// Exit initialization
builder . setAction ( text - > ShutdownHelper . exit ( ) ) . setNumberOfArguments ( 0 ) . setDescription ( " Exits the program. " ) . build ( " exit " , false ) ;
builder . build ( " q " ) ;
// Open settings scene initialization
builder . setAction ( text - > Context . getInstance ( ) . getSceneContext ( ) . load ( SceneInfo . SETTINGS_SCENE ) )
. setDescription ( " Opens the settings screen " )
. buildNoArg ( " settings " ) ;
2020-10-08 17:09:09 +02:00
// Status change initialization
builder . setAction ( text - > {
try {
UserUtil . changeStatus ( Enum . valueOf ( UserStatus . class , text . get ( 0 ) . toUpperCase ( ) ) ) ;
} catch ( final IllegalArgumentException e ) {
final var alert = new Alert ( AlertType . ERROR ) ;
alert . setContentText ( " Please provide an existing status " ) ;
alert . showAndWait ( ) ;
}
} ) . setDescription ( " Changes your status to the given status. " ) . setNumberOfArguments ( 1 ) . setDefaults ( " OFFLINE " ) . build ( " status " ) ;
2020-10-02 15:23:21 +02:00
// Selection of a new message initialization
messageDependantAction ( " s " ,
m - > { messageList . getSelectionModel ( ) . clearSelection ( ) ; messageList . getSelectionModel ( ) . select ( m ) ; } ,
m - > true ,
" Selects " ) ;
// Copy text of selection initialization
messageDependantAction ( " cp " , MessageUtil : : copyMessageText , m - > ! m . getText ( ) . isEmpty ( ) , " Copies the text of " ) ;
// Delete selection initialization
messageDependantAction ( " del " , MessageUtil : : deleteMessage , m - > true , " Deletes " ) ;
// Save attachment of selection initialization
messageDependantAction ( " save-att " , MessageUtil : : saveAttachment , Message : : hasAttachment , " Saves the attachment of " ) ;
}
private void messageDependantAction ( String command , Consumer < Message > action , Predicate < Message > additionalCheck , String description ) {
builder . setAction ( text - > {
final var positionalArgument = text . get ( 0 ) . toLowerCase ( ) ;
// the currently selected message was requested
if ( positionalArgument . startsWith ( " s " ) ) {
final var relativeString = positionalArgument . length ( ) = = 1 ? " " : positionalArgument . substring ( 1 ) ;
// Only s has been used as input
if ( positionalArgument . length ( ) = = 1 ) {
final var selectedMessage = messageList . getSelectionModel ( ) . getSelectedItem ( ) ;
if ( selectedMessage ! = null & & additionalCheck . test ( selectedMessage ) ) action . accept ( selectedMessage ) ;
return ;
// Either s++ or s-- has been requested
} else if ( relativeString . equals ( " ++ " ) | | relativeString . equals ( " -- " ) ) selectionNeighbor ( action , additionalCheck , positionalArgument ) ;
// A message relative to the currently selected message should be used (i.e.
// s+4)
else useRelativeMessage ( command , action , additionalCheck , relativeString , true ) ;
// Either ++s or --s has been requested
} else if ( positionalArgument . equals ( " --s " ) | | positionalArgument . equals ( " ++s " ) )
selectionNeighbor ( action , additionalCheck , positionalArgument ) ;
// Just a number is expected: ((+)4)
else useRelativeMessage ( command , action , additionalCheck , positionalArgument , false ) ;
} ) . setDefaults ( " s " ) . setNumberOfArguments ( 1 ) . setDescription ( description . concat ( messageDependantCommandDescription ) ) . build ( command ) ;
}
private void selectionNeighbor ( Consumer < Message > action , Predicate < Message > additionalCheck , final String positionalArgument ) {
final var wantedIndex = messageList . getSelectionModel ( ) . getSelectedIndex ( ) + ( positionalArgument . contains ( " + " ) ? 1 : - 1 ) ;
messageList . getSelectionModel ( ) . clearAndSelect ( wantedIndex ) ;
final var selectedMessage = messageList . getItems ( ) . get ( wantedIndex ) ;
if ( selectedMessage ! = null & & additionalCheck . test ( selectedMessage ) ) action . accept ( selectedMessage ) ;
}
private void useRelativeMessage ( String command , Consumer < Message > action , Predicate < Message > additionalCheck , final String positionalArgument ,
boolean useSelectedMessage ) throws NumberFormatException {
final var stripPlus = positionalArgument . startsWith ( " + " ) ? positionalArgument . substring ( 1 ) : positionalArgument ;
final var incDec = Integer . valueOf ( stripPlus ) ;
try {
// The currently selected message is the base message
if ( useSelectedMessage ) {
final var messageToUse = messageList . getItems ( ) . get ( messageList . getSelectionModel ( ) . getSelectedIndex ( ) + incDec ) ;
if ( messageToUse ! = null & & additionalCheck . test ( messageToUse ) ) action . accept ( messageToUse ) ;
// The currently upmost completely visible message is the base message
} else {
final var messageToUse = messageList . getItems ( )
. get ( ( ( VirtualFlow < ? > ) messageList . lookup ( " .virtual-flow " ) ) . getFirstVisibleCell ( ) . getIndex ( ) + 1 + incDec ) ;
if ( messageToUse ! = null & & additionalCheck . test ( messageToUse ) ) action . accept ( messageToUse ) ;
}
} catch ( final IndexOutOfBoundsException e ) {
EnvoyLog . getLogger ( ChatSceneCommands . class )
. log ( Level . INFO , " A non-existing message was requested by the user for System command " + command ) ;
}
}
/ * *
* @return the map used by this { @code ChatSceneCommands }
* @since Envoy Client v0 . 3 - beta
* /
public SystemCommandMap getChatSceneCommands ( ) { return messageTextAreaCommands ; }
}