2022-02-08 08:00:52 +00:00
// {42, 4, 336, 506}
# define WINDOW_WIDTH 502
# define WINDOW_HEIGHT 294
2021-12-05 06:27:50 +00:00
# define NK_ZERO_COMMAND_MEMORY
# define NK_INCLUDE_FIXED_TYPES
# define NK_INCLUDE_STANDARD_IO
// #define NK_INCLUDE_STANDARD_VARARGS
# define NK_INCLUDE_DEFAULT_ALLOCATOR
# define NK_IMPLEMENTATION
# define NK_QUICKDRAW_IMPLEMENTATION
// #define NK_BUTTON_TRIGGER_ON_RELEASE
# define NK_MEMSET memset
# define NK_MEMCPY memcpy
2021-11-27 07:45:53 +00:00
2022-01-10 06:57:49 +00:00
// #define MESSAGES_FOR_MACINTOSH_DEBUGGING
2022-02-24 06:00:23 +00:00
// based on https://github.com/mr21/strsplit.c/blob/master/strsplit.c
static char * * _strsplit ( const char * s , const char * delim , int * nb ) {
2022-02-24 06:34:44 +00:00
# ifdef DEBUG_FUNCTION_CALLS
writeSerialPortDebug ( boutRefNum , " DEBUG_FUNCTION_CALLS: _strsplit " ) ;
# endif
2022-02-24 06:00:23 +00:00
void * data ;
char * _s = ( char * ) s ;
const char * * ptrs ;
int
ptrsSize ,
nbWords = 1 ,
sLen = strlen ( s ) ,
delimLen = strlen ( delim ) ;
while ( ( _s = strstr ( _s , delim ) ) ) {
_s + = delimLen ;
+ + nbWords ;
2022-01-26 07:54:08 +00:00
}
2022-02-24 06:00:23 +00:00
ptrsSize = ( nbWords + 1 ) * sizeof ( char * ) ;
ptrs =
data = malloc ( ptrsSize + sLen + 1 ) ;
if ( data ) {
* ptrs =
_s = strcpy ( ( ( char * ) data ) + ptrsSize , s ) ;
if ( nbWords > 1 ) {
while ( ( _s = strstr ( _s , delim ) ) ) {
* _s = ' \0 ' ;
_s + = delimLen ;
* + + ptrs = _s ;
}
}
* + + ptrs = NULL ;
2022-01-26 07:54:08 +00:00
}
2022-02-24 06:00:23 +00:00
if ( nb ) {
* nb = data ? nbWords : 0 ;
}
return data ;
}
2022-01-26 07:54:08 +00:00
2022-02-24 06:00:23 +00:00
char * * strsplit ( const char * s , const char * delim ) {
return _strsplit ( s , delim , NULL ) ;
}
2022-01-26 07:54:08 +00:00
2022-02-24 06:00:23 +00:00
char * * strsplit_count ( const char * s , const char * delim , int * nb ) {
return _strsplit ( s , delim , nb ) ;
2022-01-26 07:54:08 +00:00
}
2021-11-28 07:48:59 +00:00
void aFailed ( char * file , int line ) {
2022-02-09 07:58:25 +00:00
# ifdef DEBUG_FUNCTION_CALLS
writeSerialPortDebug ( boutRefNum , " DEBUG_FUNCTION_CALLS: aFailed " ) ;
# endif
2021-11-28 07:48:59 +00:00
MoveTo ( 10 , 10 ) ;
2022-01-26 07:54:08 +00:00
char textoutput [ 255 ] ;
2021-11-28 07:48:59 +00:00
sprintf ( textoutput , " %s:%d " , file , line ) ;
writeSerialPortDebug ( boutRefNum , " assertion failure " ) ;
writeSerialPortDebug ( boutRefNum , textoutput ) ;
// hold the program - we want to be able to read the text! assuming anything after the assert would be a crash
while ( true ) { }
}
2022-01-26 07:54:08 +00:00
# define MAX_CHAT_MESSAGES 17
2022-02-19 07:46:29 +00:00
# define MAX_RECEIVE_SIZE 32767 // this has a corresponding value in coprocessor.c
2022-02-23 17:52:20 +00:00
# define MAX_FRIENDLY_NAME_LENGTH 64
2021-12-05 06:27:50 +00:00
2021-11-27 07:45:53 +00:00
Boolean firstOrMouseMove = true ;
2021-11-28 07:48:59 +00:00
Boolean gotMouseEvent = false ;
2022-02-23 17:52:20 +00:00
char * activeChat ;
char * activeChatMessages ;
char * box_input_buffer ;
char * chatFriendlyNames ;
char * ip_input_buffer ;
char * jsFunctionResponse ;
char * chatCountFunctionResponse ;
char * tempChatCountFunctionResponse ;
char * previousChatCountFunctionResponse ;
char * new_message_input_buffer ;
2021-11-28 07:48:59 +00:00
int activeMessageCounter = 0 ;
int chatFriendlyNamesCounter = 0 ;
int coprocessorLoaded = 0 ;
2022-02-19 07:46:29 +00:00
int forceRedrawChats = 2 ; // this is how many 'iterations' of the chat list UI that we need to see every element for, starting with 2 to draw the UI appropriately
int forceRedrawMessages = 2 ; // same as above but for messages
2021-11-28 07:48:59 +00:00
int ipAddressSet = 0 ;
int mouse_x ;
int mouse_y ;
int sendNewChat = 0 ;
2021-11-27 07:45:53 +00:00
short box_input_len ;
2021-11-28 07:48:59 +00:00
short box_len ;
2021-11-27 07:45:53 +00:00
short new_message_input_buffer_len ;
2022-02-19 07:46:29 +00:00
static short ip_input_buffer_len ;
2021-11-28 07:48:59 +00:00
struct nk_rect chats_window_size ;
struct nk_rect graphql_input_window_size ;
struct nk_rect message_input_window_size ;
struct nk_rect messages_window_size ;
2021-12-20 07:54:47 +00:00
struct nk_context * ctx ;
2022-01-26 07:54:08 +00:00
# define NK_ASSERT(e) \
if ( ! ( e ) ) \
aFailed ( __FILE__ , __LINE__ )
# include <Types.h>
# include "nuklear_quickdraw.h"
# include "coprocessorjs.h"
2021-12-20 07:54:47 +00:00
void refreshNuklearApp ( Boolean blankInput ) ;
2021-11-27 07:45:53 +00:00
void getMessagesFromjsFunctionResponse ( ) {
2022-02-09 07:58:25 +00:00
# ifdef DEBUG_FUNCTION_CALLS
writeSerialPortDebug ( boutRefNum , " DEBUG_FUNCTION_CALLS: getMessagesFromjsFunctionResponse " ) ;
# endif
2021-12-05 06:27:50 +00:00
for ( int i = 0 ; i < MAX_CHAT_MESSAGES ; i + + ) {
2021-11-27 07:45:53 +00:00
2022-02-23 17:52:20 +00:00
memset ( & activeChatMessages [ i * 2048 ] , ' \0 ' , 2048 ) ;
2021-11-28 07:48:59 +00:00
}
2021-11-27 07:45:53 +00:00
2021-11-28 07:48:59 +00:00
activeMessageCounter = 0 ;
2021-11-27 07:45:53 +00:00
2021-11-28 07:48:59 +00:00
char * token = ( char * ) strtokm ( jsFunctionResponse , " ENDLASTMESSAGE " ) ;
2022-01-10 06:57:49 +00:00
2021-11-28 07:48:59 +00:00
// loop through the string to extract all other tokens
while ( token ! = NULL ) {
2022-02-23 17:52:20 +00:00
sprintf ( & activeChatMessages [ activeMessageCounter * 2048 ] , " %s " , token ) ;
2021-11-28 07:48:59 +00:00
token = ( char * ) strtokm ( NULL , " ENDLASTMESSAGE " ) ;
activeMessageCounter + + ;
}
2021-11-27 07:45:53 +00:00
2021-11-28 07:48:59 +00:00
return ;
2021-11-27 07:45:53 +00:00
}
2021-11-28 07:48:59 +00:00
2021-11-27 07:45:53 +00:00
// function to send messages in chat
void sendMessage ( ) {
2022-02-09 07:58:25 +00:00
# ifdef DEBUG_FUNCTION_CALLS
writeSerialPortDebug ( boutRefNum , " DEBUG_FUNCTION_CALLS: sendMessage " ) ;
# endif
2021-11-28 07:48:59 +00:00
char output [ 2048 ] ;
2022-01-03 07:36:23 +00:00
sprintf ( output , " %s&&&%.*s " , activeChat , box_input_len , box_input_buffer ) ;
2021-11-27 07:45:53 +00:00
2022-02-23 17:52:20 +00:00
memset ( box_input_buffer , ' \0 ' , 2048 ) ;
2021-11-28 07:48:59 +00:00
box_input_len = 0 ;
2022-02-13 07:23:37 +00:00
// this was an attempt to get the text in the textbox to go away... doesn't really work for a few more redraws
// so actually just makes things slower:
// refreshNuklearApp(1);
2021-11-27 07:45:53 +00:00
2021-11-28 07:48:59 +00:00
callFunctionOnCoprocessor ( " sendMessage " , output , jsFunctionResponse ) ;
2021-11-27 07:45:53 +00:00
2021-11-28 07:48:59 +00:00
getMessagesFromjsFunctionResponse ( ) ;
2021-11-27 07:45:53 +00:00
2022-02-19 07:46:29 +00:00
forceRedrawMessages = 3 ;
2021-11-27 07:45:53 +00:00
2021-11-28 07:48:59 +00:00
return ;
2021-11-27 07:45:53 +00:00
}
2022-01-11 08:00:31 +00:00
// set up function to get available chat (fill buttons on the left hand side)
// interval is set by the event loop in mac_main
void getChats ( ) {
2022-02-09 07:58:25 +00:00
# ifdef DEBUG_FUNCTION_CALLS
writeSerialPortDebug ( boutRefNum , " DEBUG_FUNCTION_CALLS: getChats " ) ;
# endif
2022-01-11 08:00:31 +00:00
callFunctionOnCoprocessor ( " getChats " , " " , jsFunctionResponse ) ;
2022-02-13 07:23:37 +00:00
char * token = ( char * ) strtokm ( jsFunctionResponse , " , " ) ;
2022-01-11 08:00:31 +00:00
while ( token ! = NULL ) {
2022-02-13 07:23:37 +00:00
2022-02-26 07:35:59 +00:00
# ifdef MESSAGES_FOR_MACINTOSH_DEBUGGING
writeSerialPortDebug ( boutRefNum , token ) ;
# endif
2022-02-23 17:52:20 +00:00
sprintf ( & chatFriendlyNames [ chatFriendlyNamesCounter + + * MAX_FRIENDLY_NAME_LENGTH ] , " %s " , token ) ;
2022-01-11 08:00:31 +00:00
token = ( char * ) strtokm ( NULL , " , " ) ;
}
return ;
}
2021-11-27 07:45:53 +00:00
void sendIPAddressToCoprocessor ( ) {
2022-02-09 07:58:25 +00:00
# ifdef DEBUG_FUNCTION_CALLS
writeSerialPortDebug ( boutRefNum , " DEBUG_FUNCTION_CALLS: sendIPAddressToCoprocessor " ) ;
# endif
2021-11-28 07:48:59 +00:00
char output [ 2048 ] ;
2022-01-03 07:36:23 +00:00
sprintf ( output , " %.*s " , ip_input_buffer_len , ip_input_buffer ) ;
2021-11-27 07:45:53 +00:00
2021-11-28 07:48:59 +00:00
callFunctionOnCoprocessor ( " setIPAddress " , output , jsFunctionResponse ) ;
2021-11-27 07:45:53 +00:00
2022-01-11 08:00:31 +00:00
// now that the IP is set, we can get all of our chats
getChats ( ) ;
2021-11-28 07:48:59 +00:00
return ;
2021-11-27 07:45:53 +00:00
}
2021-12-05 06:27:50 +00:00
2021-11-27 07:45:53 +00:00
// set up function to get messages in current chat
2022-02-24 06:00:23 +00:00
// limit to recent messages
// figure out pagination?? button on the top that says "get previous chats"?, TODO
2021-11-27 07:45:53 +00:00
void getMessages ( char * thread , int page ) {
2022-02-09 07:58:25 +00:00
# ifdef DEBUG_FUNCTION_CALLS
writeSerialPortDebug ( boutRefNum , " DEBUG_FUNCTION_CALLS: getMessages " ) ;
# endif
2022-01-26 07:54:08 +00:00
char output [ 68 ] ;
2021-11-28 07:48:59 +00:00
sprintf ( output , " %s&&&%d " , thread , page ) ;
2021-11-27 07:45:53 +00:00
2021-11-28 07:48:59 +00:00
callFunctionOnCoprocessor ( " getMessages " , output , jsFunctionResponse ) ;
2021-11-27 07:45:53 +00:00
getMessagesFromjsFunctionResponse ( ) ;
2022-02-19 07:46:29 +00:00
forceRedrawMessages = 3 ;
2021-11-27 07:45:53 +00:00
2021-11-28 07:48:59 +00:00
return ;
2021-11-27 07:45:53 +00:00
}
2022-01-10 06:57:49 +00:00
// from https://stackoverflow.com/a/4770992
Boolean prefix ( const char * pre , const char * str ) {
2022-02-09 07:58:25 +00:00
# ifdef DEBUG_FUNCTION_CALLS
writeSerialPortDebug ( boutRefNum , " DEBUG_FUNCTION_CALLS: prefix " ) ;
# endif
2022-01-10 06:57:49 +00:00
return strncmp ( pre , str , strlen ( pre ) ) = = 0 ;
}
2022-01-07 06:09:39 +00:00
void getChatCounts ( ) {
2022-02-09 07:58:25 +00:00
# ifdef DEBUG_FUNCTION_CALLS
writeSerialPortDebug ( boutRefNum , " DEBUG_FUNCTION_CALLS: getChatCounts " ) ;
# endif
2022-01-26 07:54:08 +00:00
callFunctionOnCoprocessor ( " getChatCounts " , " " , chatCountFunctionResponse ) ;
2022-01-07 06:09:39 +00:00
2022-01-10 06:57:49 +00:00
# ifdef MESSAGES_FOR_MACINTOSH_DEBUGGING
writeSerialPortDebug ( boutRefNum , " getChatCounts " ) ;
2022-01-07 06:09:39 +00:00
writeSerialPortDebug ( boutRefNum , chatCountFunctionResponse ) ;
2022-01-10 06:57:49 +00:00
# endif
2022-02-13 07:23:37 +00:00
// bail out if the responses ARE equal
if ( ! strcmp ( chatCountFunctionResponse , previousChatCountFunctionResponse ) ) {
2022-01-10 06:57:49 +00:00
2022-02-26 07:35:59 +00:00
# ifdef MESSAGES_FOR_MACINTOSH_DEBUGGING
writeSerialPortDebug ( boutRefNum , " no need to update current chat count " ) ;
# endif
2022-02-13 07:23:37 +00:00
return ;
}
2022-01-26 07:54:08 +00:00
2022-02-19 07:46:29 +00:00
# ifdef MESSAGES_FOR_MACINTOSH_DEBUGGING
// TODO: if you hear a random sysbeep, it's probably caused by a mismatch here
// potentially due to a bad serial port read or allocation. needs more investigation
2022-02-13 07:23:37 +00:00
writeSerialPortDebug ( boutRefNum , " update current chat count " ) ;
writeSerialPortDebug ( boutRefNum , chatCountFunctionResponse ) ;
writeSerialPortDebug ( boutRefNum , previousChatCountFunctionResponse ) ;
2022-02-19 07:46:29 +00:00
# endif
2022-01-07 06:09:39 +00:00
2022-02-17 19:18:44 +00:00
strcpy ( previousChatCountFunctionResponse , chatCountFunctionResponse ) ;
2022-02-13 07:23:37 +00:00
SysBeep ( 1 ) ;
2022-01-10 06:57:49 +00:00
2022-02-13 07:23:37 +00:00
strcpy ( tempChatCountFunctionResponse , chatCountFunctionResponse ) ;
int chatCount = 0 ;
2022-01-07 06:09:39 +00:00
2022-02-24 06:00:23 +00:00
char * * chats = strsplit_count ( tempChatCountFunctionResponse , " , " , & chatCount ) ;
2022-01-26 07:54:08 +00:00
2022-02-13 07:23:37 +00:00
for ( int chatLoopCounter = 0 ; chatLoopCounter < chatCount ; chatLoopCounter + + ) {
2022-01-26 07:54:08 +00:00
2022-02-13 07:23:37 +00:00
# ifdef MESSAGES_FOR_MACINTOSH_DEBUGGING
writeSerialPortDebug ( boutRefNum , " DUMMY DELETE: update current chat count loop " ) ;
writeSerialPortDebug ( boutRefNum , chats [ chatLoopCounter ] ) ;
# endif
}
2022-01-26 07:54:08 +00:00
2022-02-13 07:23:37 +00:00
// loop through the string to extract all other tokens
for ( int chatLoopCounter = 0 ; chatLoopCounter < chatCount ; chatLoopCounter + + ) {
2022-01-26 07:54:08 +00:00
2022-02-13 07:23:37 +00:00
# ifdef MESSAGES_FOR_MACINTOSH_DEBUGGING
writeSerialPortDebug ( boutRefNum , " update current chat count loop " ) ;
writeSerialPortDebug ( boutRefNum , chats [ chatLoopCounter ] ) ;
# endif
2022-01-26 07:54:08 +00:00
2022-02-13 07:23:37 +00:00
// chats[chatLoopCounter] should be in format NAME:::COUNT
2022-01-26 07:54:08 +00:00
2022-02-13 07:23:37 +00:00
strcpy ( tempChatCountFunctionResponse , chatCountFunctionResponse ) ;
int results = 0 ;
2022-01-26 07:54:08 +00:00
2022-02-24 06:00:23 +00:00
char * * chatUpdate = strsplit_count ( ( char * ) chats [ chatLoopCounter ] , " ::: " , & results ) ;
2022-01-26 07:54:08 +00:00
2022-02-13 07:23:37 +00:00
if ( results ! = 2 ) {
2022-01-26 07:54:08 +00:00
2022-02-13 07:23:37 +00:00
# ifdef MESSAGES_FOR_MACINTOSH_DEBUGGING
2022-01-10 06:57:49 +00:00
char x [ 255 ] ;
2022-02-13 07:23:37 +00:00
sprintf ( x , " ERROR: chat update mismatch splitting on ':::', expected 2 results, got: %d: %s -- bailing out " , results , chats [ chatLoopCounter ] ) ;
2022-01-10 06:57:49 +00:00
writeSerialPortDebug ( boutRefNum , x ) ;
2022-01-07 06:09:39 +00:00
2022-02-13 07:23:37 +00:00
for ( int errorResultCounter = 0 ; errorResultCounter < results ; errorResultCounter + + ) {
2022-01-07 06:09:39 +00:00
2022-02-13 07:23:37 +00:00
writeSerialPortDebug ( boutRefNum , chatUpdate [ errorResultCounter ] ) ;
2022-01-10 06:57:49 +00:00
2022-02-13 07:23:37 +00:00
char y [ 255 ] ;
sprintf ( y , " %d/%d: '%s' " , errorResultCounter , results , chatUpdate [ errorResultCounter ] ) ;
writeSerialPortDebug ( boutRefNum , y ) ;
}
# endif
2022-01-07 06:09:39 +00:00
2022-02-13 07:23:37 +00:00
continue ;
}
2022-01-07 06:09:39 +00:00
2022-02-13 07:23:37 +00:00
short count = atoi ( ( char * ) chatUpdate [ 1 ] ) ;
2022-01-10 06:57:49 +00:00
2022-02-13 07:23:37 +00:00
# ifdef MESSAGES_FOR_MACINTOSH_DEBUGGING
char x [ 255 ] ;
sprintf ( x , " name: %s, countString: %s, count: %d " , chatUpdate [ 0 ] , chatUpdate [ 1 ] , count ) ;
writeSerialPortDebug ( boutRefNum , x ) ;
# endif
2022-01-10 06:57:49 +00:00
2022-02-13 07:23:37 +00:00
for ( int i = 0 ; i < chatFriendlyNamesCounter ; i + + ) {
2022-01-07 06:09:39 +00:00
2022-02-23 17:52:20 +00:00
if ( strstr ( & chatFriendlyNames [ i * MAX_FRIENDLY_NAME_LENGTH ] , " new) " ) ! = NULL ) {
2022-01-11 08:00:31 +00:00
2022-02-13 07:23:37 +00:00
char chatName [ 64 ] ;
2022-02-23 17:52:20 +00:00
sprintf ( chatName , " %.63s " , & chatFriendlyNames [ i * MAX_FRIENDLY_NAME_LENGTH ] ) ;
2022-01-11 08:00:31 +00:00
2022-02-13 07:23:37 +00:00
int updateResults = 0 ;
2022-01-07 06:09:39 +00:00
2022-02-24 06:00:23 +00:00
char * * updatePieces = strsplit_count ( chatName , " new) " , & updateResults ) ;
2022-01-10 06:57:49 +00:00
2022-02-13 07:23:37 +00:00
if ( updateResults ! = 2 ) {
2022-01-07 06:09:39 +00:00
2022-02-13 07:23:37 +00:00
# ifdef MESSAGES_FOR_MACINTOSH_DEBUGGING
char x [ 255 ] ;
sprintf ( x , " ERROR: individual chat update mismatch splitting on ' new) ', expected 2 results, got: %d: %s -- bailing out " , updateResults , chatName ) ;
writeSerialPortDebug ( boutRefNum , x ) ;
2022-01-11 08:00:31 +00:00
2022-02-13 07:23:37 +00:00
for ( int errorResultCounter = 0 ; errorResultCounter < updateResults ; errorResultCounter + + ) {
2022-01-11 08:00:31 +00:00
2022-02-13 07:23:37 +00:00
char y [ 255 ] ;
sprintf ( y , " %d/%d: '%s' " , errorResultCounter , updateResults , updatePieces [ errorResultCounter ] ) ;
writeSerialPortDebug ( boutRefNum , y ) ;
2022-01-11 08:00:31 +00:00
}
2022-02-13 07:23:37 +00:00
# endif
continue ;
}
if ( prefix ( ( char * ) updatePieces [ 1 ] , ( char * ) chatUpdate [ 0 ] ) ) {
2022-01-26 07:54:08 +00:00
# ifdef MESSAGES_FOR_MACINTOSH_DEBUGGING
2022-02-13 07:23:37 +00:00
writeSerialPortDebug ( boutRefNum , " match1 " ) ;
2022-01-26 07:54:08 +00:00
writeSerialPortDebug ( boutRefNum , chatUpdate [ 0 ] ) ;
# endif
2022-02-07 06:51:27 +00:00
if ( count = = 0 | | ! strcmp ( activeChat , ( char * ) chatUpdate [ 0 ] ) ) {
2022-01-26 07:54:08 +00:00
2022-02-23 17:52:20 +00:00
sprintf ( & chatFriendlyNames [ i * MAX_FRIENDLY_NAME_LENGTH ] , " %.63s " , ( char * ) chatUpdate [ 0 ] ) ;
2022-01-26 07:54:08 +00:00
} else {
2022-02-23 17:52:20 +00:00
sprintf ( & chatFriendlyNames [ i * MAX_FRIENDLY_NAME_LENGTH ] , " (%d new) %.63s " , count , ( char * ) chatUpdate [ 0 ] ) ;
2022-01-26 07:54:08 +00:00
}
break ;
2022-01-07 06:09:39 +00:00
}
2022-02-23 17:52:20 +00:00
} else if ( prefix ( & chatFriendlyNames [ i * MAX_FRIENDLY_NAME_LENGTH ] , ( char * ) chatUpdate [ 0 ] ) ) {
2022-01-07 06:09:39 +00:00
2022-02-13 07:23:37 +00:00
# ifdef MESSAGES_FOR_MACINTOSH_DEBUGGING
writeSerialPortDebug ( boutRefNum , " match2 " ) ;
writeSerialPortDebug ( boutRefNum , chatUpdate [ 0 ] ) ;
# endif
2022-01-10 06:57:49 +00:00
2022-02-13 07:23:37 +00:00
if ( count = = 0 | | ! strcmp ( activeChat , ( char * ) chatUpdate [ 0 ] ) ) {
2022-02-23 17:52:20 +00:00
sprintf ( & chatFriendlyNames [ i * MAX_FRIENDLY_NAME_LENGTH ] , " %.63s " , ( char * ) chatUpdate [ 0 ] ) ;
2022-02-13 07:23:37 +00:00
} else {
2022-02-23 17:52:20 +00:00
sprintf ( & chatFriendlyNames [ i * MAX_FRIENDLY_NAME_LENGTH ] , " (%d new) %.63s " , count , ( char * ) chatUpdate [ 0 ] ) ;
2022-02-13 07:23:37 +00:00
}
break ;
}
}
2022-01-07 06:09:39 +00:00
}
2022-02-19 07:46:29 +00:00
forceRedrawChats = 3 ;
2022-02-13 07:23:37 +00:00
2022-01-07 06:09:39 +00:00
return ;
}
2021-11-27 07:45:53 +00:00
void getHasNewMessagesInChat ( char * thread ) {
2022-02-09 07:58:25 +00:00
# ifdef DEBUG_FUNCTION_CALLS
writeSerialPortDebug ( boutRefNum , " DEBUG_FUNCTION_CALLS: getHasNewMessagesInChat " ) ;
# endif
2022-01-26 07:54:08 +00:00
char output [ 68 ] ;
2021-11-28 07:48:59 +00:00
sprintf ( output , " %s " , thread ) ;
2021-11-27 07:45:53 +00:00
2021-11-28 07:48:59 +00:00
callFunctionOnCoprocessor ( " hasNewMessagesInChat " , output , jsFunctionResponse ) ;
2021-11-27 07:45:53 +00:00
if ( ! strcmp ( jsFunctionResponse , " true " ) ) {
2022-02-26 07:35:59 +00:00
# ifdef MESSAGES_FOR_MACINTOSH_DEBUGGING
writeSerialPortDebug ( boutRefNum , " update current chat " ) ;
# endif
2021-11-28 07:48:59 +00:00
SysBeep ( 1 ) ;
getMessages ( thread , 0 ) ;
}
2022-02-26 07:35:59 +00:00
# ifdef MESSAGES_FOR_MACINTOSH_DEBUGGING
else {
writeSerialPortDebug ( boutRefNum , " do not update current chat " ) ;
}
# endif
2021-11-27 07:45:53 +00:00
2021-11-28 07:48:59 +00:00
return ;
2021-11-27 07:45:53 +00:00
}
2021-12-20 07:54:47 +00:00
2021-11-27 07:45:53 +00:00
Boolean chatWindowCollision ;
Boolean messageWindowCollision ;
Boolean checkCollision ( struct nk_rect window ) {
2022-02-09 07:58:25 +00:00
# ifdef DEBUG_FUNCTION_CALLS
writeSerialPortDebug ( boutRefNum , " DEBUG_FUNCTION_CALLS: checkCollision " ) ;
# endif
2021-11-27 07:45:53 +00:00
2021-11-28 07:48:59 +00:00
// if truthy return, mouse is over window!
return ( window . x < mouse_x & &
window . x + window . w > mouse_x & &
window . y < mouse_y & &
window . y + window . h > mouse_y ) ;
2021-11-27 07:45:53 +00:00
}
2021-11-29 07:25:07 +00:00
// UI setup and event handling goes here
2021-11-28 07:48:59 +00:00
static void nuklearApp ( struct nk_context * ctx ) {
2021-11-27 07:45:53 +00:00
2022-02-09 07:58:25 +00:00
# ifdef DEBUG_FUNCTION_CALLS
writeSerialPortDebug ( boutRefNum , " DEBUG_FUNCTION_CALLS: nuklearApp " ) ;
# endif
2021-11-28 07:48:59 +00:00
// prompt the user for the graphql instance
if ( ! coprocessorLoaded ) {
2021-11-27 07:45:53 +00:00
2021-11-28 07:48:59 +00:00
if ( nk_begin_titled ( ctx , " Loading coprocessor services " , " Loading coprocessor services " , graphql_input_window_size , NK_WINDOW_TITLE | NK_WINDOW_BORDER ) ) {
2021-11-27 07:45:53 +00:00
2021-11-28 07:48:59 +00:00
nk_layout_row_begin ( ctx , NK_STATIC , 20 , 1 ) ;
{
nk_layout_row_push ( ctx , 200 ) ;
nk_label_wrap ( ctx , " Please wait " ) ;
}
nk_layout_row_end ( ctx ) ;
2021-11-27 07:45:53 +00:00
2021-11-28 07:48:59 +00:00
nk_end ( ctx ) ;
}
2021-11-27 07:45:53 +00:00
2021-11-28 07:48:59 +00:00
return ;
}
2021-11-27 07:45:53 +00:00
2021-11-28 07:48:59 +00:00
// prompt the user for the graphql instance
if ( ! ipAddressSet ) {
2021-11-27 07:45:53 +00:00
2021-11-28 07:48:59 +00:00
if ( nk_begin_titled ( ctx , " Enter iMessage GraphQL Server " , " Enter iMessage GraphQL Server " , graphql_input_window_size , NK_WINDOW_TITLE | NK_WINDOW_BORDER ) ) {
2021-11-27 07:45:53 +00:00
2021-11-28 07:48:59 +00:00
nk_layout_row_begin ( ctx , NK_STATIC , 20 , 1 ) ;
{
nk_layout_row_push ( ctx , 200 ) ;
nk_label_wrap ( ctx , " ex: http://127.0.0.1 " ) ;
}
nk_layout_row_end ( ctx ) ;
2021-11-27 07:45:53 +00:00
2021-11-28 07:48:59 +00:00
nk_layout_row_begin ( ctx , NK_STATIC , 30 , 2 ) ;
{
2021-11-27 07:45:53 +00:00
2021-12-05 06:27:50 +00:00
nk_layout_row_push ( ctx , WINDOW_WIDTH / 2 - 100 ) ;
2022-02-09 07:58:25 +00:00
short ip_edit_return_value = nk_edit_string ( ctx , NK_EDIT_ALWAYS_INSERT_MODE | NK_EDIT_GOTO_END_ON_ACTIVATE , ip_input_buffer , & ip_input_buffer_len , 255 , nk_filter_default ) ;
2021-12-05 06:27:50 +00:00
nk_layout_row_push ( ctx , 55 ) ;
2021-11-27 07:45:53 +00:00
2022-02-09 07:58:25 +00:00
if ( nk_button_label ( ctx , " save " ) | | ip_edit_return_value = = 17 ) {
2021-11-28 07:48:59 +00:00
ipAddressSet = 1 ;
2022-02-19 07:46:29 +00:00
forceRedrawChats = 2 ;
forceRedrawMessages = 2 ;
2021-11-28 07:48:59 +00:00
sendIPAddressToCoprocessor ( ) ;
}
}
nk_layout_row_end ( ctx ) ;
2021-11-27 07:45:53 +00:00
2021-11-28 07:48:59 +00:00
nk_end ( ctx ) ;
}
2021-11-27 07:45:53 +00:00
2022-02-09 07:58:25 +00:00
// eliminate the initially-set force-redraw
2022-02-19 07:46:29 +00:00
if ( forceRedrawChats ) {
2022-02-09 07:58:25 +00:00
2022-02-19 07:46:29 +00:00
forceRedrawChats - - ;
}
if ( forceRedrawMessages ) {
forceRedrawMessages - - ;
2022-02-09 07:58:25 +00:00
}
2021-11-28 07:48:59 +00:00
return ;
}
2021-11-27 07:45:53 +00:00
2022-01-26 07:54:08 +00:00
// prompt the user for new chat
2021-11-28 07:48:59 +00:00
if ( sendNewChat ) {
2021-11-27 07:45:53 +00:00
2022-01-03 07:36:23 +00:00
if ( nk_begin_titled ( ctx , " Enter New Message Recipient " , " Enter New Message Recipient " , nk_rect ( 50 , WINDOW_HEIGHT / 4 , WINDOW_WIDTH - 100 , 140 ) , NK_WINDOW_TITLE | NK_WINDOW_BORDER ) ) {
2021-11-27 07:45:53 +00:00
2022-01-03 07:36:23 +00:00
nk_layout_row_begin ( ctx , NK_STATIC , 30 , 1 ) ;
2021-11-28 07:48:59 +00:00
{
2022-01-03 07:36:23 +00:00
nk_layout_row_push ( ctx , WINDOW_WIDTH - 120 ) ;
2022-01-11 08:00:31 +00:00
nk_label ( ctx , " enter contact name as it would appear " , NK_TEXT_ALIGN_LEFT ) ;
2022-01-03 07:36:23 +00:00
nk_layout_row_push ( ctx , WINDOW_WIDTH - 120 ) ;
2022-01-11 08:00:31 +00:00
nk_label ( ctx , " on your iPhone, iPad, modern Mac, etc " , NK_TEXT_ALIGN_LEFT ) ;
2022-01-03 07:36:23 +00:00
}
nk_layout_row_end ( ctx ) ;
2021-11-27 07:45:53 +00:00
2022-01-03 07:36:23 +00:00
nk_layout_row_begin ( ctx , NK_STATIC , 30 , 2 ) ;
{
nk_layout_row_push ( ctx , WINDOW_WIDTH / 2 ) ;
2021-11-28 07:48:59 +00:00
nk_edit_string ( ctx , NK_EDIT_SIMPLE , new_message_input_buffer , & new_message_input_buffer_len , 2048 , nk_filter_default ) ;
2022-01-03 07:36:23 +00:00
nk_layout_row_push ( ctx , 100 ) ;
2021-12-05 06:27:50 +00:00
2021-11-28 07:48:59 +00:00
if ( nk_button_label ( ctx , " open chat " ) ) {
sendNewChat = 0 ;
2022-02-19 07:46:29 +00:00
forceRedrawChats = 2 ;
forceRedrawMessages = 2 ;
2021-11-27 07:45:53 +00:00
2022-01-03 07:36:23 +00:00
sprintf ( activeChat , " %.*s " , new_message_input_buffer_len , new_message_input_buffer ) ;
for ( int i = 0 ; i < MAX_CHAT_MESSAGES ; i + + ) {
2022-02-23 17:52:20 +00:00
memset ( & activeChatMessages [ i * 2048 ] , ' \0 ' , 2048 ) ;
2022-01-03 07:36:23 +00:00
}
2022-01-11 08:00:31 +00:00
getMessages ( activeChat , 0 ) ;
2021-11-28 07:48:59 +00:00
}
}
nk_layout_row_end ( ctx ) ;
2021-11-27 07:45:53 +00:00
2021-11-28 07:48:59 +00:00
nk_end ( ctx ) ;
}
2021-11-27 07:45:53 +00:00
2021-11-28 07:48:59 +00:00
return ;
}
2021-11-27 07:45:53 +00:00
2021-11-28 07:48:59 +00:00
chatWindowCollision = checkCollision ( chats_window_size ) ;
2021-11-27 07:45:53 +00:00
2022-02-19 07:46:29 +00:00
if ( ( chatWindowCollision | | forceRedrawChats ) & & nk_begin ( ctx , " Chats " , chats_window_size , NK_WINDOW_BORDER | NK_WINDOW_NO_SCROLLBAR ) ) {
// we force a redraw for several following iterations in case the mouse has moved away,
// we want to ensure that the button highlighting disappears
2022-02-20 07:12:28 +00:00
if ( chatWindowCollision & & firstOrMouseMove ) {
2022-02-19 07:46:29 +00:00
forceRedrawChats = 3 ;
}
2021-11-27 07:45:53 +00:00
2021-11-28 07:48:59 +00:00
nk_layout_row_begin ( ctx , NK_STATIC , 25 , 1 ) ;
{
for ( int i = 0 ; i < chatFriendlyNamesCounter ; i + + ) {
2021-11-27 07:45:53 +00:00
2021-11-28 07:48:59 +00:00
// only display the first 8 chats, create new chat if you need someone not in your list
if ( i > 9 ) {
2021-11-27 07:45:53 +00:00
2021-11-28 07:48:59 +00:00
continue ;
}
2021-11-27 07:45:53 +00:00
2021-11-28 07:48:59 +00:00
nk_layout_row_push ( ctx , 169 ) ;
2021-11-27 07:45:53 +00:00
2022-02-23 17:52:20 +00:00
if ( nk_button_label ( ctx , & chatFriendlyNames [ i * MAX_FRIENDLY_NAME_LENGTH ] ) ) {
2021-11-27 07:45:53 +00:00
2022-02-23 17:52:20 +00:00
if ( strstr ( & chatFriendlyNames [ i * MAX_FRIENDLY_NAME_LENGTH ] , " new) " ) ! = NULL ) {
2022-01-10 06:57:49 +00:00
char chatName [ 96 ] ;
2022-02-23 17:52:20 +00:00
sprintf ( chatName , " %.63s " , & chatFriendlyNames [ i * MAX_FRIENDLY_NAME_LENGTH ] ) ;
2022-01-11 08:00:31 +00:00
# ifdef MESSAGES_FOR_MACINTOSH_DEBUGGING
writeSerialPortDebug ( boutRefNum , " clicked1 chatName " ) ;
writeSerialPortDebug ( boutRefNum , chatName ) ;
# endif
2022-01-10 06:57:49 +00:00
// we are throwing out the first token
2022-01-11 08:00:31 +00:00
char * name = ( char * ) strtokm ( chatName , " new) " ) ;
# ifdef MESSAGES_FOR_MACINTOSH_DEBUGGING
writeSerialPortDebug ( boutRefNum , " clicked1 portion1 of string, will toss " ) ;
writeSerialPortDebug ( boutRefNum , name ) ;
# endif
name = ( char * ) strtokm ( NULL , " new) " ) ;
# ifdef MESSAGES_FOR_MACINTOSH_DEBUGGING
writeSerialPortDebug ( boutRefNum , " clicked1 have name to assign to activeChat " ) ;
writeSerialPortDebug ( boutRefNum , name ) ;
# endif
2022-01-10 06:57:49 +00:00
2022-01-26 07:54:08 +00:00
sprintf ( activeChat , " %.63s " , name ) ;
2022-02-23 17:52:20 +00:00
sprintf ( & chatFriendlyNames [ i * MAX_FRIENDLY_NAME_LENGTH ] , " %.63s " , name ) ;
2022-01-10 06:57:49 +00:00
} else {
2022-01-11 08:00:31 +00:00
# ifdef MESSAGES_FOR_MACINTOSH_DEBUGGING
writeSerialPortDebug ( boutRefNum , " clicked2 chatName " ) ;
2022-02-23 17:52:20 +00:00
writeSerialPortDebug ( boutRefNum , chatFriendlyNames [ i * MAX_FRIENDLY_NAME_LENGTH ] ) ;
2022-01-11 08:00:31 +00:00
# endif
2022-02-23 17:52:20 +00:00
sprintf ( activeChat , " %.63s " , & chatFriendlyNames [ i * MAX_FRIENDLY_NAME_LENGTH ] ) ;
2022-01-10 06:57:49 +00:00
}
2022-02-20 07:12:28 +00:00
forceRedrawChats = 6 ; // redraw the chat list for several iterations in an attempt to get rid of the hovered button
2021-11-28 07:48:59 +00:00
getMessages ( activeChat , 0 ) ;
}
}
}
nk_layout_row_end ( ctx ) ;
2021-11-27 07:45:53 +00:00
2021-11-28 07:48:59 +00:00
nk_end ( ctx ) ;
2021-11-27 07:45:53 +00:00
}
if ( nk_begin ( ctx , " Message Input " , message_input_window_size , NK_WINDOW_BORDER | NK_WINDOW_NO_SCROLLBAR ) ) {
2021-12-05 06:27:50 +00:00
// bottom text input
2021-11-28 07:48:59 +00:00
nk_layout_row_begin ( ctx , NK_STATIC , 28 , 1 ) ;
{
2022-02-08 08:00:52 +00:00
nk_layout_row_push ( ctx , 312 ) ;
2021-11-27 07:45:53 +00:00
2022-02-09 07:58:25 +00:00
nk_edit_focus ( ctx , NK_EDIT_ALWAYS_INSERT_MODE ) ;
2021-11-28 07:48:59 +00:00
short edit_return_value = nk_edit_string ( ctx , NK_EDIT_FIELD | NK_EDIT_SIG_ENTER , box_input_buffer , & box_input_len , 2048 , nk_filter_default ) ;
2021-11-27 07:45:53 +00:00
2021-11-28 07:48:59 +00:00
// this is the enter key, obviously
2022-02-15 07:23:51 +00:00
if ( edit_return_value = = 17 & & box_input_len > 0 ) {
2021-11-27 07:45:53 +00:00
2021-11-28 07:48:59 +00:00
sendMessage ( ) ;
}
}
nk_layout_row_end ( ctx ) ;
2021-11-27 07:45:53 +00:00
2021-11-28 07:48:59 +00:00
nk_end ( ctx ) ;
}
2021-11-27 07:45:53 +00:00
2022-02-19 07:46:29 +00:00
if ( ( forceRedrawMessages ) & & nk_begin_titled ( ctx , " Message " , activeChat , messages_window_size , NK_WINDOW_BORDER | NK_WINDOW_TITLE | NK_WINDOW_NO_SCROLLBAR ) ) {
2021-11-27 07:45:53 +00:00
2022-02-08 08:00:52 +00:00
nk_layout_row_begin ( ctx , NK_STATIC , 11 , 1 ) ;
2021-11-28 07:48:59 +00:00
{
2021-11-29 07:25:07 +00:00
2021-11-28 07:48:59 +00:00
for ( int i = 0 ; i < activeMessageCounter ; i + + ) {
2021-11-29 07:25:07 +00:00
2021-11-28 07:48:59 +00:00
nk_layout_row_push ( ctx , 305 ) ;
2022-01-26 07:54:08 +00:00
// writeSerialPortDebug(boutRefNum, "activeChatMessages[i]");
// writeSerialPortDebug(boutRefNum, activeChatMessages[i]);
2022-02-23 17:52:20 +00:00
nk_label ( ctx , & activeChatMessages [ i * 2048 ] , NK_TEXT_ALIGN_LEFT ) ;
2021-11-28 07:48:59 +00:00
}
}
nk_layout_row_end ( ctx ) ;
nk_end ( ctx ) ;
2021-11-27 07:45:53 +00:00
}
2022-02-19 07:46:29 +00:00
if ( forceRedrawChats ) {
forceRedrawChats - - ;
}
if ( forceRedrawMessages ) {
2021-11-28 07:48:59 +00:00
2022-02-19 07:46:29 +00:00
forceRedrawMessages - - ;
2021-11-28 07:48:59 +00:00
}
}
2021-12-05 06:27:50 +00:00
void refreshNuklearApp ( Boolean blankInput ) {
2022-02-09 07:58:25 +00:00
# ifdef DEBUG_FUNCTION_CALLS
writeSerialPortDebug ( boutRefNum , " DEBUG_FUNCTION_CALLS: refreshNuklearApp " ) ;
# endif
2021-12-05 06:27:50 +00:00
nk_input_begin ( ctx ) ;
if ( blankInput ) {
nk_input_key ( ctx , NK_KEY_DEL , 1 ) ;
nk_input_key ( ctx , NK_KEY_DEL , 0 ) ;
}
nk_input_end ( ctx ) ;
nuklearApp ( ctx ) ;
nk_quickdraw_render ( FrontWindow ( ) , ctx ) ;
nk_clear ( ctx ) ;
}
2021-11-28 07:48:59 +00:00
struct nk_context * initializeNuklearApp ( ) {
2021-11-27 07:45:53 +00:00
2022-02-09 07:58:25 +00:00
# ifdef DEBUG_FUNCTION_CALLS
writeSerialPortDebug ( boutRefNum , " DEBUG_FUNCTION_CALLS: initializeNuklearApp " ) ;
# endif
2022-02-23 17:52:20 +00:00
activeChat = malloc ( sizeof ( char ) * MAX_FRIENDLY_NAME_LENGTH ) ;
activeChatMessages = malloc ( sizeof ( char ) * ( MAX_CHAT_MESSAGES * 2048 ) ) ; // this should match to MAX_ROWS in index.js
box_input_buffer = malloc ( sizeof ( char ) * 2048 ) ;
chatFriendlyNames = malloc ( sizeof ( char ) * ( 16 * MAX_FRIENDLY_NAME_LENGTH ) ) ;
ip_input_buffer = malloc ( sizeof ( char ) * 255 ) ;
jsFunctionResponse = malloc ( sizeof ( char ) * MAX_RECEIVE_SIZE ) ;
chatCountFunctionResponse = malloc ( sizeof ( char ) * MAX_RECEIVE_SIZE ) ;
tempChatCountFunctionResponse = malloc ( sizeof ( char ) * MAX_RECEIVE_SIZE ) ;
previousChatCountFunctionResponse = malloc ( sizeof ( char ) * MAX_RECEIVE_SIZE ) ;
new_message_input_buffer = malloc ( sizeof ( char ) * 255 ) ;
2021-11-28 07:48:59 +00:00
sprintf ( activeChat , " no active chat " ) ;
2021-11-29 07:25:07 +00:00
2021-12-05 06:27:50 +00:00
graphql_input_window_size = nk_rect ( WINDOW_WIDTH / 2 - 118 , 80 , 234 , 100 ) ;
2021-11-28 07:48:59 +00:00
chats_window_size = nk_rect ( 0 , 0 , 180 , WINDOW_HEIGHT ) ;
messages_window_size = nk_rect ( 180 , 0 , 330 , WINDOW_HEIGHT - 36 ) ;
message_input_window_size = nk_rect ( 180 , WINDOW_HEIGHT - 36 , 330 , 36 ) ;
2021-11-29 07:25:07 +00:00
2021-12-05 06:27:50 +00:00
ctx = nk_quickdraw_init ( WINDOW_WIDTH , WINDOW_HEIGHT ) ;
refreshNuklearApp ( false ) ;
2021-11-27 07:45:53 +00:00
2022-02-19 07:46:29 +00:00
sprintf ( ip_input_buffer , " http:// " ) ;
2022-01-26 07:54:08 +00:00
ip_input_buffer_len = 7 ;
2021-11-27 07:45:53 +00:00
2021-11-28 07:48:59 +00:00
return ctx ;
2021-11-27 07:45:53 +00:00
}