2024-07-07 13:43:18 +02:00
(() => {
2024-07-07 22:11:18 +02:00
// node_modules/uuid/dist/esm-browser/stringify.js
var byteToHex = [];
for ( i = 0 ; i < 256 ; ++ i ) {
byteToHex . push (( i + 256 ). toString ( 16 ). slice ( 1 ));
}
var i ;
function unsafeStringify ( arr , offset = 0 ) {
return ( byteToHex [ arr [ offset + 0 ]] + byteToHex [ arr [ offset + 1 ]] + byteToHex [ arr [ offset + 2 ]] + byteToHex [ arr [ offset + 3 ]] + "-" + byteToHex [ arr [ offset + 4 ]] + byteToHex [ arr [ offset + 5 ]] + "-" + byteToHex [ arr [ offset + 6 ]] + byteToHex [ arr [ offset + 7 ]] + "-" + byteToHex [ arr [ offset + 8 ]] + byteToHex [ arr [ offset + 9 ]] + "-" + byteToHex [ arr [ offset + 10 ]] + byteToHex [ arr [ offset + 11 ]] + byteToHex [ arr [ offset + 12 ]] + byteToHex [ arr [ offset + 13 ]] + byteToHex [ arr [ offset + 14 ]] + byteToHex [ arr [ offset + 15 ]]). toLowerCase ();
}
// node_modules/uuid/dist/esm-browser/rng.js
var getRandomValues ;
var rnds8 = new Uint8Array ( 16 );
function rng () {
if ( ! getRandomValues ) {
getRandomValues = typeof crypto !== "undefined" && crypto . getRandomValues && crypto . getRandomValues . bind ( crypto );
if ( ! getRandomValues ) {
throw new Error ( "crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported" );
}
}
return getRandomValues ( rnds8 );
}
// node_modules/uuid/dist/esm-browser/native.js
var randomUUID = typeof crypto !== "undefined" && crypto . randomUUID && crypto . randomUUID . bind ( crypto );
var native_default = {
randomUUID
};
// node_modules/uuid/dist/esm-browser/v4.js
function v4 ( options , buf , offset ) {
if ( native_default . randomUUID && ! buf && ! options ) {
return native_default . randomUUID ();
}
options = options || {};
var rnds = options . random || ( options . rng || rng )();
rnds [ 6 ] = rnds [ 6 ] & 15 | 64 ;
rnds [ 8 ] = rnds [ 8 ] & 63 | 128 ;
if ( buf ) {
offset = offset || 0 ;
for ( var i = 0 ; i < 16 ; ++ i ) {
buf [ offset + i ] = rnds [ i ];
}
return buf ;
}
return unsafeStringify ( rnds );
}
var v4_default = v4 ;
2024-07-07 19:21:08 +02:00
// node_modules/bloatless-react/index.ts
2024-07-07 22:11:18 +02:00
function UUID () {
return v4_default ();
}
var State = class {
_value ;
_bindings = /* @__PURE__ */ new Set ();
// init
constructor ( initialValue ) {
this . _value = initialValue ;
}
// value
get value () {
return this . _value ;
}
set value ( newValue ) {
if ( this . _value == newValue ) return ;
this . _value = newValue ;
this . callSubscriptions ();
}
// subscriptions
callSubscriptions () {
this . _bindings . forEach (( fn ) => fn ( this . _value ));
}
subscribe ( fn ) {
this . _bindings . add ( fn );
fn ( this . _value );
}
2024-07-11 15:08:25 +02:00
subscribeSilent ( fn ) {
this . _bindings . add ( fn );
}
2024-07-07 22:11:18 +02:00
// stringify
toString () {
return JSON . stringify ( this . _value );
}
};
var ListState = class extends State {
additionHandlers = /* @__PURE__ */ new Set ();
removalHandlers = /* @__PURE__ */ new Map ();
// init
constructor ( initialItems ) {
super ( new Set ( initialItems ));
}
// list
add (... items ) {
items . forEach (( item ) => {
this . value . add ( item );
this . additionHandlers . forEach (( handler ) => handler ( item ));
});
this . callSubscriptions ();
}
remove (... items ) {
items . forEach (( item ) => {
this . value . delete ( item );
2024-07-09 14:11:20 +02:00
if ( ! this . removalHandlers . has ( item )) return ;
2024-07-15 19:22:49 +02:00
this . removalHandlers . get ( item ). forEach (( handler ) => handler ( item ));
2024-07-09 14:11:20 +02:00
this . removalHandlers . delete ( item );
2024-07-07 22:11:18 +02:00
});
this . callSubscriptions ();
}
2024-07-08 00:39:22 +02:00
clear () {
this . remove (... this . value . values ());
}
2024-07-07 22:11:18 +02:00
// handlers
handleAddition ( handler ) {
this . additionHandlers . add ( handler );
[... this . value . values ()]. forEach ( handler );
}
handleRemoval ( item , handler ) {
2024-07-15 19:22:49 +02:00
if ( ! this . removalHandlers . has ( item ))
this . removalHandlers . set ( item , /* @__PURE__ */ new Set ());
this . removalHandlers . get ( item ). add ( handler );
2024-07-07 22:11:18 +02:00
}
// stringification
toString () {
2024-07-11 00:47:58 +02:00
const array = [... this . value . values ()];
const json = JSON . stringify ( array );
return json ;
}
};
var MapState = class extends State {
additionHandlers = /* @__PURE__ */ new Set ();
removalHandlers = /* @__PURE__ */ new Map ();
// init
constructor ( initialItems ) {
super ( new Map ( initialItems ));
}
// list
set ( key , item ) {
2024-07-11 01:18:34 +02:00
this . remove ( key );
2024-07-11 00:47:58 +02:00
this . value . set ( key , item );
this . additionHandlers . forEach (( handler ) => handler ( item ));
this . callSubscriptions ();
}
remove ( key ) {
const item = this . value . get ( key );
if ( ! item ) return ;
this . value . delete ( key );
this . callSubscriptions ();
if ( ! this . removalHandlers . has ( item )) return ;
2024-07-15 19:22:49 +02:00
this . removalHandlers . get ( item ). forEach (( handler ) => handler ( item ));
2024-07-11 00:47:58 +02:00
this . removalHandlers . delete ( item );
}
clear () {
2024-07-11 02:29:00 +02:00
[... this . value . keys ()]. forEach (( key ) => this . remove ( key ));
2024-07-11 00:47:58 +02:00
}
// handlers
handleAddition ( handler ) {
this . additionHandlers . add ( handler );
[... this . value . values ()]. forEach ( handler );
}
handleRemoval ( item , handler ) {
2024-07-15 19:22:49 +02:00
if ( ! this . removalHandlers . has ( item ))
this . removalHandlers . set ( item , /* @__PURE__ */ new Set ());
this . removalHandlers . get ( item ). add ( handler );
2024-07-11 00:47:58 +02:00
}
// stringification
toString () {
const array = [... this . value . entries ()];
2024-07-07 22:11:18 +02:00
const json = JSON . stringify ( array );
return json ;
}
};
function createProxyState ( statesToSubscibe , fn ) {
const proxyState = new State ( fn ());
statesToSubscibe . forEach (
( state ) => state . subscribe (() => proxyState . value = fn ())
);
return proxyState ;
}
2024-07-11 15:08:25 +02:00
function bulkSubscribe ( statesToSubscibe , fn ) {
statesToSubscibe . forEach (( state ) => state . subscribeSilent ( fn ));
}
2024-07-07 22:11:18 +02:00
function persistState ( localStorageKey , state ) {
state . subscribe (() => {
const stringifiedValue = state . toString ();
localStorage . setItem ( localStorageKey , stringifiedValue );
});
}
function restoreState ( localStorageKey , initialStateValue ) {
const storedString = localStorage . getItem ( localStorageKey ) ?? JSON . stringify ( initialStateValue );
const convertedValue = JSON . parse ( storedString );
const state = new State ( convertedValue );
persistState ( localStorageKey , state );
return state ;
}
2024-07-11 00:47:58 +02:00
function restoreListState ( localStorageKey , initialItems = []) {
2024-07-07 22:11:18 +02:00
const storedString = localStorage . getItem ( localStorageKey ) ?? "" ;
try {
const array = JSON . parse ( storedString );
if ( ! Array . isArray ( array )) throw "" ;
initialItems = array ;
} catch {
}
const state = new ListState ( initialItems );
persistState ( localStorageKey , state );
return state ;
}
2024-07-11 00:47:58 +02:00
function restoreMapState ( localStorageKey , initialItems = []) {
const storedString = localStorage . getItem ( localStorageKey ) ?? "" ;
try {
const array = JSON . parse ( storedString );
if ( ! Array . isArray ( array )) throw "" ;
initialItems = array ;
} catch {
}
const state = new MapState ( initialItems );
persistState ( localStorageKey , state );
return state ;
}
2024-07-07 19:21:08 +02:00
function createElement ( tagName , attributes = {}, ... children ) {
const element = document . createElement ( tagName );
if ( attributes != null )
Object . entries ( attributes ). forEach (( entry ) => {
const [ attributename , value ] = entry ;
const [ directiveKey , directiveValue ] = attributename . split ( ":" );
switch ( directiveKey ) {
case "on" : {
switch ( directiveValue ) {
case "enter" : {
element . addEventListener ( "keydown" , ( e ) => {
if ( e . key != "Enter" ) return ;
value ();
});
break ;
}
default : {
element . addEventListener ( directiveValue , value );
}
}
break ;
}
case "subscribe" : {
2024-07-09 14:11:20 +02:00
const state = value ;
state . subscribe (
( newValue ) => element [ directiveValue ] = newValue
);
2024-07-07 19:21:08 +02:00
break ;
}
case "bind" : {
const state = value ;
state . subscribe (
( newValue ) => element [ directiveValue ] = newValue
);
element . addEventListener (
"input" ,
() => state . value = element [ directiveValue ]
);
break ;
}
case "toggle" : {
2024-07-08 00:39:22 +02:00
if ( value . subscribe ) {
const state = value ;
state . subscribe (
( newValue ) => element . toggleAttribute ( directiveValue , newValue )
);
} else {
element . toggleAttribute ( directiveValue , value );
}
2024-07-07 19:21:08 +02:00
break ;
}
case "set" : {
const state = value ;
state . subscribe (
( newValue ) => element . setAttribute ( directiveValue , newValue )
);
break ;
}
2024-07-09 14:11:20 +02:00
case "children" : {
switch ( directiveValue ) {
case "set" : {
const state = value ;
state . subscribe (( newValue ) => {
element . innerHTML = "" ;
2024-07-09 18:21:28 +02:00
element . append (...[ newValue ]. flat ());
2024-07-09 14:11:20 +02:00
});
break ;
}
case "append" :
case "appendandscroll" :
case "prepend" : {
element . style . scrollBehavior = "smooth" ;
try {
const [ listState , toElement ] = value ;
listState . handleAddition (( newItem ) => {
const child = toElement ( newItem );
listState . handleRemoval (
newItem ,
() => child . remove ()
);
if ( directiveValue == "append" ) {
element . append ( child );
} else if ( directiveValue == "prepend" ) {
element . prepend ( child );
}
});
} catch {
2024-07-11 00:56:06 +02:00
throw `error: cannot process subscribe:children directive because StateItemConverter is not defined. Usage: "subscribe:children={[list, converter]}"; you can find a more detailed example in the documentation` ;
2024-07-09 14:11:20 +02:00
}
}
}
}
2024-07-07 19:21:08 +02:00
default :
element . setAttribute ( attributename , value );
}
});
children . filter (( x ) => x ). forEach (( child ) => element . append ( child ));
return element ;
}
2024-07-08 00:39:22 +02:00
// src/cryptUtility.ts
var IV_SIZE = 12 ;
var ENCRYPTION_ALG = "AES-GCM" ;
2024-07-09 14:11:20 +02:00
async function encryptString ( plaintext , passphrase ) {
2024-07-10 15:08:06 +02:00
if ( ! window . crypto . subtle ) return plaintext ;
2024-07-09 14:11:20 +02:00
const iv = generateIV ();
const key = await importKey ( passphrase , "encrypt" );
const encryptedArray = await encrypt ( iv , key , plaintext );
const encryptionData = {
iv : uInt8ToArray ( iv ),
encryptedArray : uInt8ToArray ( encryptedArray )
};
return btoa ( JSON . stringify ( encryptionData ));
}
async function decryptString ( cyphertext , passphrase ) {
try {
const encrypionData = JSON . parse ( atob ( cyphertext ));
const iv = arrayToUint8 ( encrypionData . iv );
const encryptedArray = arrayToUint8 ( encrypionData . encryptedArray );
const key = await importKey ( passphrase , "decrypt" );
return await decrypt ( iv , key , encryptedArray );
} catch {
return cyphertext ;
}
}
2024-07-08 00:39:22 +02:00
function encode ( string ) {
return new TextEncoder (). encode ( string );
}
function decode ( array ) {
return new TextDecoder ( "utf-8" ). decode ( array );
}
async function encrypt ( iv , key , message ) {
const arrayBuffer = await window . crypto . subtle . encrypt (
{ name : ENCRYPTION_ALG , iv },
key ,
encode ( message )
);
return new Uint8Array ( arrayBuffer );
}
async function decrypt ( iv , key , cyphertext ) {
const arrayBuffer = await crypto . subtle . decrypt (
{ name : ENCRYPTION_ALG , iv },
key ,
cyphertext
);
return arrayBufferToString ( arrayBuffer );
}
async function hash ( encoded ) {
return await crypto . subtle . digest ( "SHA-256" , encoded );
}
function generateIV () {
return crypto . getRandomValues ( new Uint8Array ( IV_SIZE ));
}
async function importKey ( passphrase , purpose ) {
return await crypto . subtle . importKey (
"raw" ,
await hash ( encode ( passphrase )),
{ name : ENCRYPTION_ALG },
false ,
[ purpose ]
);
}
function arrayBufferToString ( arrayBuffer ) {
const uInt8Array = new Uint8Array ( arrayBuffer );
return decode ( uInt8Array );
}
function uInt8ToArray ( uInt8Array ) {
return Array . from ( uInt8Array );
}
function arrayToUint8 ( array ) {
return new Uint8Array ( array );
}
2024-07-12 02:24:48 +02:00
// src/utility.tsx
2024-07-09 14:11:20 +02:00
var storageKeys = {
2024-07-12 02:30:50 +02:00
viewType ( id ) {
return id + "view-type" ;
},
2024-07-10 15:40:25 +02:00
hasUnread ( id ) {
return id + "has-unread-messages" ;
},
2024-07-09 14:11:20 +02:00
primaryChannel ( id ) {
return id + "primary-channel" ;
},
secondaryChannels ( id ) {
return id + "secondary-channels" ;
},
encyptionKey ( id ) {
return id + "encryption-key" ;
},
messages ( id ) {
return id + "messages" ;
},
2024-07-11 01:47:43 +02:00
objects ( id ) {
2024-07-11 00:47:58 +02:00
return id + "items" ;
},
2024-07-10 16:37:42 +02:00
outbox ( id ) {
return id + "outbox" ;
},
2024-07-11 01:18:34 +02:00
itemOutbox ( id ) {
return id + "item-outbox" ;
},
2024-07-09 14:11:20 +02:00
composingMessage ( id ) {
return id + "composing-message" ;
}
};
2024-07-12 02:24:48 +02:00
var stringToOptionTag = ( value ) => {
return /* @__PURE__ */ createElement ( "option" , null , value );
};
2024-07-09 14:11:20 +02:00
2024-07-11 21:02:28 +02:00
// src/translations.ts
var englishTranslations = {
// general
set : "Set" ,
save : "Save" ,
2024-07-13 17:13:59 +02:00
search : "Search" ,
reset : "Reset" ,
2024-07-11 21:02:28 +02:00
back : "Back" ,
undoChanges : "Undo changes" ,
close : "Close" ,
discard : "Discard" ,
2024-07-12 01:54:53 +02:00
rename : "Rename" ,
2024-07-12 21:11:33 +02:00
// settings
settings : "Settings" ,
showSettings : "Show settings" ,
zoomOut : "Zoom Out" ,
zoomIn : "Zoom In" ,
repairApp : "Repair App" ,
2024-07-12 22:24:54 +02:00
clearAddresses : "Clear previous connections" ,
clearCategories : "Clear suggestions for object categories" ,
clearStatuses : "Clear suggestions for object statuses" ,
2024-07-17 17:22:16 +00:00
clearObjectFilters : "Clear object filters" ,
2024-07-11 21:02:28 +02:00
// overview
overview : "Overview" ,
connection : "Connection" ,
chats : "Chats" ,
yourName : "Your Name" ,
namePlaceholder : "Jane Doe" ,
encryptionUnavailableTitle : "Encryption is not available" ,
encryptionUnavailableMessage : "Obtain this app via HTTPS or continue without encryption" ,
serverAddress : "Server Address" ,
serverAddressPlaceholder : "wss://192.168.0.69:3000" ,
2024-07-12 19:58:29 +02:00
previousConnections : "Previous connections" ,
2024-07-11 21:02:28 +02:00
connectToServer : "Connect" ,
disconnect : "Disconnect" ,
mailbox : "Mailbox" ,
requestMailbox : "Enable" ,
deleteMailbox : "Disable" ,
mailboxExplanation : "When you're disconnected, messages will be kept on the server temporarily" ,
outbox : "Outbox" ,
outboxText : ( count ) => {
switch ( count ) {
case 0 :
return "All items sent" ;
case 1 :
return "1 item in outbox" ;
default :
return ` ${ count } items in outbox` ;
}
},
primaryChannel : "Primary channel" ,
primaryChannelPlaceholder : "my-channel" ,
addChat : "Add" ,
// chat
showChatOptions : "show chat options" ,
configureChatTitle : "Configure Chat" ,
secondaryChannel : "Secondary channel" ,
secondaryChannelPlaceholder : "Add secondary channel" ,
addSecondaryChannel : "Add secondary channel" ,
removeSecondaryChannel : "Remove secondary channel" ,
encryptionKey : "Encryption key" ,
encryptionKeyPlaceholder : "n10d2482dg283hg" ,
showKey : "Show key" ,
clearObjects : "Delete all objects" ,
clearChatMessages : "Clear chat messages" ,
removeChat : "Remove chat" ,
messageInOutbox : "Pending" ,
noChatSelected : "No chat selected" ,
composerPlaceholder : "Type a message..." ,
sendMessage : "Send" ,
// messages
resendMessage : "Resend message" ,
decryptMessage : "Decrypt message" ,
copyMessage : "Copy message" ,
deleteMessage : "Delete message" ,
// objects
2024-07-12 20:40:03 +02:00
objectsInTotal : "Objects in total: " ,
2024-07-11 21:02:28 +02:00
showObjects : "show objects" ,
createObject : "create object" ,
untitledObject : "Untitled Object" ,
2024-07-13 17:13:59 +02:00
filterObjects : "Filter Objects" ,
2024-07-17 14:25:11 +00:00
searchTitle : "Search" ,
searchPlaceholder : "Note 2000-12-31" ,
searchTitleText : ( term , resultCount ) => term == "" ? `Objects in total: ${ resultCount } ` : `Matches for " ${ term } ": ${ resultCount } ` ,
2024-07-11 21:02:28 +02:00
viewAll : "All" ,
viewNotes : "Notes" ,
2024-07-12 00:43:58 +02:00
viewKanban : "Kanban" ,
2024-07-12 14:30:30 +02:00
viewStatus : "Status" ,
2024-07-11 21:02:28 +02:00
noObjects : "No objects" ,
objectTitle : "Object title" ,
objectTitlePlaceholder : "My object" ,
objectVersion : "Object version" ,
2024-07-11 21:30:57 +02:00
note : "Note" ,
2024-07-11 21:02:28 +02:00
noteContentPlaceholder : "Take a note..." ,
2024-07-11 21:30:57 +02:00
category : "Category" ,
2024-07-12 14:30:30 +02:00
categoryPlaceholder : "Define a category" ,
2024-07-11 21:30:57 +02:00
priority : "Priority" ,
priorityPlaceholder : "2" ,
2024-07-12 14:30:30 +02:00
status : "Status" ,
statusPlaceholder : "Pending" ,
2024-07-11 21:30:57 +02:00
date : "Date" ,
time : "Time" ,
2024-07-11 21:02:28 +02:00
resendObjects : "Resend all objects" ,
deleteObject : "Delete object"
};
var allTranslations = {
en : englishTranslations ,
es : {
// general
set : "Guardar" ,
save : "Guardar" ,
2024-07-13 17:13:59 +02:00
search : "Buscar" ,
reset : "Restablecer" ,
2024-07-11 21:02:28 +02:00
back : "Atr\xE1s" ,
undoChanges : "Deshacer" ,
close : "Cerrar" ,
discard : "Descartar" ,
2024-07-12 01:54:53 +02:00
rename : "Renombrar" ,
2024-07-12 21:11:33 +02:00
// settings
settings : "Configuraci\xF3n" ,
showSettings : "Mostrar configuraci\xF3n" ,
zoomOut : "Alejar" ,
zoomIn : "Acercar" ,
repairApp : "Reparar Aplicaci\xF3n" ,
2024-07-12 22:24:54 +02:00
clearAddresses : "Borrar conexiones previas" ,
clearCategories : "Borrar sugerencias para categor\xEDas de objetos" ,
clearStatuses : "Borrar sugerencias para estados de objetos" ,
2024-07-17 17:22:16 +00:00
clearObjectFilters : "Borrar filtros de objetos" ,
2024-07-11 21:02:28 +02:00
// overview
overview : "Resumen" ,
connection : "Conexi\xF3n" ,
chats : "Chats" ,
yourName : "Tu nombre" ,
namePlaceholder : "Juan P\xE9rez" ,
encryptionUnavailableTitle : "Cifrado no disponible" ,
2024-07-17 17:22:16 +00:00
encryptionUnavailableMessage : "Obt\xE9n esta aplicaci\xF3n a trav\xE9s de HTTPS o contin\xFAa sin cifrado" ,
2024-07-11 21:02:28 +02:00
serverAddress : "Direcci\xF3n del servidor" ,
serverAddressPlaceholder : "wss://192.168.0.69:3000" ,
2024-07-12 19:58:29 +02:00
previousConnections : "Conexiones anteriores" ,
2024-07-11 21:02:28 +02:00
connectToServer : "Conectar" ,
disconnect : "Desconectar" ,
mailbox : "Buz\xF3n" ,
requestMailbox : "Activar" ,
deleteMailbox : "Desactivar" ,
mailboxExplanation : "Si est\xE1s sin conexi\xF3n, los mensajes se guardar\xE1n temporalmente en el servidor" ,
outbox : "Bandeja de salida" ,
outboxText : ( count ) => {
switch ( count ) {
case 0 :
return "Todos los elementos enviados" ;
case 1 :
return "1 elemento en bandeja de salida" ;
default :
return ` ${ count } elementos en bandeja de salida` ;
}
},
primaryChannel : "Canal principal" ,
primaryChannelPlaceholder : "mi-canal" ,
addChat : "A\xF1adir" ,
// chat
showChatOptions : "Mostrar opciones del chat" ,
configureChatTitle : "Configurar chat" ,
secondaryChannel : "Canal secundario" ,
secondaryChannelPlaceholder : "A\xF1adir canal secundario" ,
addSecondaryChannel : "A\xF1adir canal secundario" ,
removeSecondaryChannel : "Eliminar canal secundario" ,
encryptionKey : "Clave de cifrado" ,
encryptionKeyPlaceholder : "n10d2482dg283hg" ,
showKey : "Mostrar clave" ,
clearObjects : "Eliminar todos los objetos" ,
clearChatMessages : "Eliminar todos los mensajes" ,
removeChat : "Eliminar chat" ,
messageInOutbox : "Pendiente" ,
noChatSelected : "Selecciona un chat" ,
composerPlaceholder : "Escribe un mensaje..." ,
sendMessage : "Enviar" ,
// messages
resendMessage : "Reenviar mensaje" ,
decryptMessage : "Descifrar mensaje" ,
copyMessage : "Copiar mensaje" ,
deleteMessage : "Eliminar este mensaje" ,
// objects
2024-07-12 20:40:03 +02:00
objectsInTotal : "Objetos en total: " ,
2024-07-11 21:02:28 +02:00
showObjects : "mostrar objetos" ,
createObject : "a\xF1adir nuevo objeto" ,
2024-07-17 17:22:16 +00:00
untitledObject : "Sin t\xEDtulo" ,
2024-07-14 20:08:01 +02:00
filterObjects : "Filtrar objetos" ,
2024-07-17 14:25:11 +00:00
searchTitle : "Buscar" ,
searchPlaceholder : "Nota 2000-12-31" ,
2024-07-13 17:16:12 +02:00
searchTitleText : ( term , resultCount ) => term == "" ? `Objetos en total: ${ resultCount } ` : `Resultados por " ${ term } ": ${ resultCount } ` ,
2024-07-11 21:02:28 +02:00
viewAll : "Todos" ,
viewNotes : "Notas" ,
2024-07-12 00:43:58 +02:00
viewKanban : "Kanban" ,
2024-07-12 14:30:30 +02:00
viewStatus : "Estado" ,
2024-07-11 21:02:28 +02:00
noObjects : "Sin objetos" ,
objectTitle : "T\xEDtulo" ,
objectTitlePlaceholder : "Mi objeto" ,
objectVersion : "Version del objeto" ,
2024-07-11 21:30:57 +02:00
note : "Nota" ,
2024-07-11 21:02:28 +02:00
noteContentPlaceholder : "Toma nota..." ,
2024-07-11 22:58:22 +02:00
category : "Categor\xEDa" ,
2024-07-12 14:30:30 +02:00
categoryPlaceholder : "Define una categor\xEDa" ,
2024-07-11 22:58:22 +02:00
priority : "Prioridad" ,
priorityPlaceholder : "2" ,
2024-07-12 14:30:30 +02:00
status : "Estado" ,
statusPlaceholder : "Pendiente" ,
2024-07-11 22:58:22 +02:00
date : "Fecha" ,
time : "Hora" ,
2024-07-13 12:16:35 +02:00
resendObjects : "Reenviar todos los objetos" ,
2024-07-11 21:02:28 +02:00
deleteObject : "Eliminar objeto"
},
de : {
// general
set : "OK" ,
save : "Sichern" ,
2024-07-13 17:13:59 +02:00
search : "Suchen" ,
reset : "Zur\xFCcksetzen" ,
2024-07-11 21:02:28 +02:00
back : "Zur\xFCck" ,
undoChanges : "\xC4nderungen verwerfen" ,
close : "Schlie\xDFen" ,
discard : "Verwerfen" ,
2024-07-12 01:54:53 +02:00
rename : "Umbenennen" ,
2024-07-12 21:11:33 +02:00
// settings
settings : "Einstellungen" ,
showSettings : "Einstellungen anzeigen" ,
zoomOut : "Verkleinern" ,
zoomIn : "Vergr\xF6\xDFern" ,
repairApp : "App reparieren" ,
2024-07-12 22:24:54 +02:00
clearAddresses : "Vorherige Verbindungen l\xF6schen" ,
clearCategories : "Vorschl\xE4ge f\xFCr Objektkategorien l\xF6schen" ,
clearStatuses : "Vorschl\xE4ge f\xFCr Objektstaten l\xF6schen" ,
2024-07-17 17:22:16 +00:00
clearObjectFilters : "Objektfilter l\xF6schen" ,
2024-07-11 21:02:28 +02:00
// overview
overview : "\xDCbersicht" ,
connection : "Verbindung" ,
chats : "Chats" ,
yourName : "Dein Name" ,
namePlaceholder : "Max Mustermann" ,
encryptionUnavailableTitle : "Verschl\xFCsselung nicht m\xF6glich" ,
encryptionUnavailableMessage : "Lade diese app \xFCber HTTPS, um Nachrichten zu verschl\xFCsseln" ,
serverAddress : "Serveradresse" ,
serverAddressPlaceholder : "wss://192.168.0.69:3000" ,
2024-07-12 22:24:54 +02:00
previousConnections : "Vorherige Verbindungen" ,
2024-07-11 21:02:28 +02:00
connectToServer : "Verbinden" ,
disconnect : "Trennen" ,
mailbox : "Briefkasten" ,
requestMailbox : "Aktivieren" ,
deleteMailbox : "Deaktivieren" ,
mailboxExplanation : "Wenn du offline bist, werden Nachrichten auf dem Server gelagert" ,
outbox : "Ausgang" ,
outboxText : ( count ) => {
switch ( count ) {
case 0 :
return "Alle Nachrichten gesendet" ;
case 1 :
return "Eine Nachricht ausstehend" ;
default :
return ` ${ count } Nachrichten ausstehend` ;
}
},
primaryChannel : "Hauptkanal" ,
primaryChannelPlaceholder : "mein-kanal" ,
addChat : "Hinzuf\xFCgen" ,
// chat
showChatOptions : "Chatoptionen einblenden" ,
configureChatTitle : "Chat konfigurieren" ,
secondaryChannel : "Zweitkanal" ,
secondaryChannelPlaceholder : "Zweitkanal hinzuf\xFCgen" ,
addSecondaryChannel : "Zweitkanal hinzuf\xFCgen" ,
removeSecondaryChannel : "Zweitkanal entfernen" ,
encryptionKey : "Schl\xFCssel" ,
encryptionKeyPlaceholder : "n10d2482dg283hg" ,
showKey : "Schl\xFCssel anzeigen" ,
clearObjects : "Alle Objekte l\xF6schen" ,
clearChatMessages : "Nachrichtenverlauf leeren" ,
removeChat : "Chat l\xF6schen" ,
messageInOutbox : "Ausstehend" ,
noChatSelected : "Kein Chat ausgew\xE4hlt" ,
composerPlaceholder : "Neue Nachricht..." ,
sendMessage : "Senden" ,
// messages
resendMessage : "Erneut senden" ,
decryptMessage : "Nachricht entschl\xFCsseln" ,
copyMessage : "Nachricht kopieren" ,
deleteMessage : "Nachricht l\xF6schen" ,
// objects
2024-07-12 20:40:03 +02:00
objectsInTotal : "Objekte insgesamt: " ,
2024-07-11 21:02:28 +02:00
showObjects : "Objekte anzeigen" ,
createObject : "Neues Objekt erstellen" ,
untitledObject : "Unbenannt" ,
2024-07-13 17:13:59 +02:00
filterObjects : "Objekte filtern" ,
2024-07-17 14:25:11 +00:00
searchTitle : "Suchen" ,
searchPlaceholder : "Notiz 2000-12-31" ,
2024-07-13 17:16:12 +02:00
searchTitleText : ( term , resultCount ) => term == "" ? `Objekte insgesamt: ${ resultCount } ` : `Ergebnisse f\xFCr " ${ term } ": ${ resultCount } ` ,
2024-07-11 21:02:28 +02:00
viewAll : "Alle" ,
viewNotes : "Notizen" ,
2024-07-12 00:43:58 +02:00
viewKanban : "Kanban" ,
2024-07-12 14:30:30 +02:00
viewStatus : "Status" ,
2024-07-11 21:02:28 +02:00
noObjects : "Keine Objekte" ,
objectTitle : "Titel" ,
objectTitlePlaceholder : "Mein Objekt" ,
objectVersion : "Version des Objekts" ,
2024-07-11 21:30:57 +02:00
note : "Notiz" ,
2024-07-11 21:02:28 +02:00
noteContentPlaceholder : "Notiz eingeben..." ,
2024-07-11 22:58:22 +02:00
category : "Kategorie" ,
2024-07-12 14:30:30 +02:00
categoryPlaceholder : "Kategorie eingeben..." ,
2024-07-11 22:58:22 +02:00
priority : "Priorit\xE4t" ,
priorityPlaceholder : "2" ,
2024-07-12 14:30:30 +02:00
status : "Status" ,
statusPlaceholder : "Ausstehend" ,
2024-07-11 22:58:22 +02:00
date : "Datum" ,
time : "Uhrzeit" ,
2024-07-11 21:02:28 +02:00
resendObjects : "Objekte erneut senden" ,
deleteObject : "Objekt l\xF6schen"
}
};
var language = navigator . language . substring ( 0 , 2 );
var translation = allTranslations [ language ] ?? allTranslations . en ;
2024-07-09 14:11:20 +02:00
// src/Model/chatModel.ts
var Chat = class {
id ;
2024-07-12 02:30:50 +02:00
viewType ;
2024-07-09 14:11:20 +02:00
isSubscribed = new State ( false );
2024-07-09 17:23:29 +02:00
primaryChannel = new State ( "" );
2024-07-10 15:40:25 +02:00
hasUnreadMessages ;
2024-07-09 14:11:20 +02:00
secondaryChannels ;
encryptionKey ;
messages ;
2024-07-11 01:47:43 +02:00
objects ;
2024-07-10 16:37:42 +02:00
outbox ;
2024-07-11 01:47:43 +02:00
objectOutbox ;
2024-07-10 16:37:42 +02:00
isOutBoxEmpty ;
2024-07-09 14:11:20 +02:00
composingMessage ;
2024-07-09 17:23:29 +02:00
primaryChannelInput ;
2024-07-10 15:40:25 +02:00
newSecondaryChannelName ;
2024-07-09 14:11:20 +02:00
cannotSendMessage ;
2024-07-10 15:08:06 +02:00
cannotResendMessage ;
2024-07-09 14:11:20 +02:00
cannotAddSecondaryChannel ;
cannotSetChannel ;
2024-07-09 17:23:29 +02:00
cannotUndoChannel ;
2024-07-09 21:56:00 +02:00
cannotClearMessages ;
2024-07-11 02:29:00 +02:00
cannotClearObjects ;
2024-07-09 14:11:20 +02:00
// init
constructor ( id = UUID ()) {
2024-07-09 15:15:17 +02:00
this . id = id ;
2024-07-12 02:30:50 +02:00
this . viewType = restoreState (
storageKeys . viewType ( id ),
"all"
);
2024-07-09 17:23:29 +02:00
this . primaryChannel = restoreState (
2024-07-09 14:11:20 +02:00
storageKeys . primaryChannel ( id ),
""
);
this . secondaryChannels = restoreListState (
storageKeys . secondaryChannels ( id )
);
2024-07-10 15:40:25 +02:00
this . hasUnreadMessages = restoreState (
storageKeys . hasUnread ( id ),
false
);
2024-07-09 14:11:20 +02:00
this . encryptionKey = restoreState ( storageKeys . encyptionKey ( id ), "" );
this . messages = restoreListState ( storageKeys . messages ( id ));
2024-07-11 01:47:43 +02:00
this . objects = restoreMapState ( storageKeys . objects ( id ));
2024-07-10 16:37:42 +02:00
this . outbox = restoreListState ( storageKeys . outbox ( id ));
2024-07-11 02:09:44 +02:00
this . objectOutbox = restoreMapState ( storageKeys . itemOutbox ( id ));
2024-07-10 16:37:42 +02:00
this . isOutBoxEmpty = createProxyState (
[ this . outbox ],
() => this . outbox . value . size == 0
);
2024-07-11 20:16:28 +02:00
bulkSubscribe (
[ this . outbox , this . objectOutbox ],
() => this . updateOutboxCount ()
);
this . updateOutboxCount ();
2024-07-09 14:11:20 +02:00
this . composingMessage = restoreState (
storageKeys . composingMessage ( id ),
""
);
this . newSecondaryChannelName = new State ( "" );
2024-07-09 17:23:29 +02:00
this . primaryChannelInput = new State ( this . primaryChannel . value );
2024-07-09 14:11:20 +02:00
this . cannotSendMessage = createProxyState (
2024-07-10 16:37:42 +02:00
[ this . primaryChannel , this . composingMessage , senderName ],
() => this . primaryChannel . value == "" || this . composingMessage . value == "" || senderName . value == ""
2024-07-09 14:11:20 +02:00
);
2024-07-10 15:08:06 +02:00
this . cannotResendMessage = createProxyState (
2024-07-10 16:37:42 +02:00
[ this . primaryChannel , senderName ],
() => this . primaryChannel . value == "" || senderName . value == ""
2024-07-10 15:08:06 +02:00
);
2024-07-09 14:11:20 +02:00
this . cannotAddSecondaryChannel = createProxyState (
[ this . newSecondaryChannelName ],
() => this . newSecondaryChannelName . value == ""
);
this . cannotSetChannel = createProxyState (
2024-07-09 17:23:29 +02:00
[ this . primaryChannelInput , this . primaryChannel ],
() => this . primaryChannelInput . value == "" || this . primaryChannelInput . value == this . primaryChannel . value
);
this . cannotUndoChannel = createProxyState (
[ this . primaryChannelInput , this . primaryChannel ],
() => this . primaryChannelInput . value == this . primaryChannel . value
2024-07-09 14:11:20 +02:00
);
2024-07-09 21:56:00 +02:00
this . cannotClearMessages = createProxyState (
[ this . messages ],
() => this . messages . value . size == 0
);
2024-07-11 02:29:00 +02:00
this . cannotClearObjects = createProxyState (
[ this . objects ],
() => this . objects . value . size == 0
);
2024-07-09 14:11:20 +02:00
}
2024-07-09 17:32:51 +02:00
// general
deleteSelf = () => {
Object . values ( storageKeys ). forEach (( storageKey ) => {
localStorage . removeItem ( storageKey ( this . id ));
});
chats . remove ( this );
chatIds . remove ( this . id );
};
2024-07-09 14:11:20 +02:00
// handlers
2024-07-09 17:23:29 +02:00
onmessage = async ( data ) => {
2024-07-09 18:44:13 +02:00
if ( ! data . messageChannel ) return ;
const channels = data . messageChannel . split ( "/" );
2024-07-09 18:51:46 +02:00
if ( channels . indexOf ( this . primaryChannel . value ) == - 1 ) return ;
2024-07-09 14:11:20 +02:00
if ( data . subscribed != void 0 ) this . handleSubscription ( data . subscribed );
if ( ! data . messageBody ) return ;
2024-07-11 14:03:15 +02:00
const message = JSON . parse ( data . messageBody );
const { sender , body , channel , isoDate , messageObjectString } = message ;
if ( messageObjectString ) {
const decryptedMessageObjectString = await decryptString (
messageObjectString ,
2024-07-11 12:25:45 +02:00
this . encryptionKey . value
);
2024-07-11 14:03:15 +02:00
const messageObject = JSON . parse ( decryptedMessageObjectString );
2024-07-11 21:02:28 +02:00
if ( messageObject . id ) return this . handleMessageObject ( messageObject );
2024-07-11 00:47:58 +02:00
}
2024-07-09 17:23:29 +02:00
this . handleMessage ({
sender ,
body : await decryptString ( body , this . encryptionKey . value ),
channel ,
isoDate
});
};
handleSubscription = ( isSubscribed ) => {
2024-07-09 14:11:20 +02:00
this . isSubscribed . value = isSubscribed ;
2024-07-10 16:37:42 +02:00
if ( isSubscribed == true ) {
this . sendMessagesInOutbox ();
}
2024-07-09 17:23:29 +02:00
};
handleMessage = ( chatMessage ) => {
2024-07-09 14:11:20 +02:00
this . messages . add ( chatMessage );
2024-07-10 15:40:25 +02:00
if ( selectedChat . value != this ) this . hasUnreadMessages . value = true ;
2024-07-09 17:23:29 +02:00
};
2024-07-11 01:47:43 +02:00
handleMessageObject = ( messageObject ) => {
2024-07-12 22:24:54 +02:00
this . addObject ( messageObject , true );
2024-07-10 15:08:06 +02:00
};
2024-07-11 12:25:45 +02:00
// sending
sendMessagesInOutbox = () => {
this . outbox . value . forEach ( async ( message ) => {
const isSent = await this . sendMessage ( message );
if ( isSent == true ) this . outbox . remove ( message );
});
2024-07-11 14:03:15 +02:00
this . objectOutbox . value . forEach ( async ( messageObject ) => {
const chatMessage = await this . createChatMessage ( "" , messageObject );
2024-07-11 12:25:45 +02:00
const isSent = await this . sendMessage ( chatMessage );
2024-07-11 14:03:15 +02:00
if ( isSent == true ) this . objectOutbox . remove ( messageObject . id );
2024-07-11 12:25:45 +02:00
});
};
2024-07-11 20:16:28 +02:00
updateOutboxCount () {
outboxItemCount . value = this . outbox . value . size + this . objectOutbox . value . size ;
}
2024-07-11 00:47:58 +02:00
// messages
2024-07-11 01:47:43 +02:00
createChatMessage = async ( messageText , messageObject ) => {
2024-07-09 14:11:20 +02:00
const secondaryChannelNames = [
... this . secondaryChannels . value . values ()
2024-07-09 18:44:13 +02:00
];
2024-07-09 14:11:20 +02:00
const allChannelNames = [
2024-07-09 17:23:29 +02:00
this . primaryChannel . value ,
2024-07-09 14:11:20 +02:00
... secondaryChannelNames
];
const joinedChannelName = allChannelNames . join ( "/" );
2024-07-11 01:47:43 +02:00
const chatMessage = {
2024-07-09 14:11:20 +02:00
channel : joinedChannelName ,
sender : senderName . value ,
2024-07-10 16:47:29 +02:00
body : messageText ,
2024-07-09 14:11:20 +02:00
isoDate : ( /* @__PURE__ */ new Date ()). toISOString ()
};
2024-07-11 12:25:45 +02:00
if ( messageObject )
2024-07-11 14:03:15 +02:00
chatMessage . messageObjectString = await encryptString (
2024-07-11 12:25:45 +02:00
JSON . stringify ( messageObject ),
this . encryptionKey . value
);
2024-07-11 01:47:43 +02:00
return chatMessage ;
2024-07-10 16:37:42 +02:00
};
2024-07-11 00:47:58 +02:00
sendMessageFromComposer = async () => {
if ( this . cannotSendMessage . value == true ) return ;
await this . sendMessageFromText ( this . composingMessage . value );
this . composingMessage . value = "" ;
};
sendMessageFromText = async ( text ) => {
2024-07-11 01:47:43 +02:00
const chatMessage = await this . createChatMessage ( text );
2024-07-11 02:09:44 +02:00
this . outbox . add ( chatMessage );
this . sendMessagesInOutbox ();
2024-07-11 00:47:58 +02:00
};
2024-07-11 01:47:43 +02:00
resendMessage = ( chatMessage ) => {
2024-07-11 00:47:58 +02:00
if ( this . cannotResendMessage . value == true ) return ;
2024-07-11 01:47:43 +02:00
this . sendMessageFromText ( chatMessage . body );
2024-07-11 00:47:58 +02:00
};
2024-07-09 17:23:29 +02:00
clearMessages = () => {
2024-07-09 14:11:20 +02:00
this . messages . clear ();
2024-07-09 17:23:29 +02:00
};
2024-07-11 01:47:43 +02:00
deleteMessage = ( chatMessage ) => {
this . messages . remove ( chatMessage );
2024-07-09 17:23:29 +02:00
};
2024-07-11 01:47:43 +02:00
deleteOutboxMessage = ( chatMessage ) => {
this . outbox . remove ( chatMessage );
2024-07-10 16:37:42 +02:00
};
2024-07-11 01:47:43 +02:00
decryptReceivedMessage = async ( chatMessage ) => {
2024-07-11 02:09:44 +02:00
chatMessage . body = await decryptString (
chatMessage . body ,
this . encryptionKey . value
);
2024-07-09 14:11:20 +02:00
this . messages . callSubscriptions ();
2024-07-09 17:23:29 +02:00
};
2024-07-11 02:09:44 +02:00
sendMessage = async ( chatMessage ) => {
2024-07-11 12:25:45 +02:00
if ( isConnected . value == false || this . isSubscribed . value == false )
return false ;
2024-07-11 02:09:44 +02:00
const encryptedBody = this . encryptionKey . value == "" ? chatMessage . body : await encryptString ( chatMessage . body , this . encryptionKey . value );
chatMessage . body = encryptedBody ;
const messageString = JSON . stringify ( chatMessage );
UDN . sendMessage ( chatMessage . channel , messageString );
2024-07-11 12:25:45 +02:00
return true ;
2024-07-11 02:09:44 +02:00
};
2024-07-11 01:47:43 +02:00
// objects
2024-07-11 13:05:02 +02:00
createObjectFromTitle = ( title ) => {
2024-07-11 16:45:45 +02:00
const firstObjectContent = this . createObjectContent ();
const messageObject = {
2024-07-11 13:05:02 +02:00
id : UUID (),
title ,
2024-07-11 16:45:45 +02:00
contentVersions : {}
2024-07-11 13:05:02 +02:00
};
2024-07-11 16:45:45 +02:00
this . addObjectContent ( messageObject , firstObjectContent );
return messageObject ;
2024-07-11 13:05:02 +02:00
};
2024-07-11 16:45:45 +02:00
createObjectContent = () => {
return {
id : UUID (),
isoDateVersionCreated : ( /* @__PURE__ */ new Date ()). toISOString ()
};
2024-07-11 13:05:02 +02:00
};
2024-07-11 16:45:45 +02:00
addObjectContent = ( messageObject , content ) => {
messageObject . contentVersions [ content . id ] = content ;
};
2024-07-13 11:56:15 +02:00
updateObjectContent = ( messageObject , content ) => {
const latest = this . getMostRecentContent ( messageObject );
Object . entries ( content ). forEach (( entry ) => {
const [ key , value ] = entry ;
latest [ key ] = value ;
});
this . addObjectContent ( messageObject , latest );
};
2024-07-12 22:24:54 +02:00
addObject = ( messageObject , ignoreIfUnchanged = false ) => {
2024-07-11 16:45:45 +02:00
const existingObject = this . objects . value . get ( messageObject . id );
if ( existingObject ) {
2024-07-13 11:24:58 +02:00
let isIdentical = existingObject . title == messageObject . title ;
2024-07-11 16:45:45 +02:00
existingObject . title = messageObject . title ;
Object . values ( messageObject . contentVersions ). forEach (( content ) => {
2024-07-12 20:49:08 +02:00
if ( existingObject . contentVersions [ content . id ]) return ;
2024-07-11 16:45:45 +02:00
this . addObjectContent ( existingObject , content );
2024-07-13 11:24:58 +02:00
isIdentical = false ;
2024-07-11 16:45:45 +02:00
});
2024-07-13 11:24:58 +02:00
if ( isIdentical && ignoreIfUnchanged ) return ;
2024-07-11 16:45:45 +02:00
this . objects . set ( existingObject . id , existingObject );
} else {
this . objects . set ( messageObject . id , messageObject );
2024-07-11 15:08:25 +02:00
}
2024-07-12 02:24:48 +02:00
const latest = this . getMostRecentContent ( messageObject );
2024-07-12 15:09:57 +02:00
if ( ! latest ) return ;
if ( latest . categoryName ) usedObjectCategories . add ( latest . categoryName );
if ( latest . status ) usedObjectStatuses . add ( latest . status );
2024-07-11 13:05:02 +02:00
};
2024-07-11 14:03:15 +02:00
addObjectAndSend = ( messageObject ) => {
this . addObject ( messageObject );
this . sendObject ( messageObject );
2024-07-11 02:29:00 +02:00
};
2024-07-11 14:03:15 +02:00
sendObject = ( messageObject ) => {
this . objectOutbox . set ( messageObject . id , messageObject );
2024-07-11 02:09:44 +02:00
this . sendMessagesInOutbox ();
2024-07-11 02:29:00 +02:00
};
2024-07-11 14:03:15 +02:00
deleteObject = ( messageObject ) => {
this . objects . remove ( messageObject . id );
this . objectOutbox . remove ( messageObject . id );
2024-07-11 02:29:00 +02:00
};
resendObjects = () => {
2024-07-11 13:05:02 +02:00
this . objects . value . forEach (( messageObject ) => {
this . sendObject ( messageObject );
2024-07-11 02:29:00 +02:00
});
};
clearObjects = () => {
this . objects . clear ();
};
2024-07-11 16:45:45 +02:00
getSortedContents = ( messageObject ) => {
const contents = Object . values ( messageObject . contentVersions );
contents . sort (
2024-07-11 20:53:53 +02:00
( a , b ) => a . isoDateVersionCreated > b . isoDateVersionCreated ? - 1 : 1
2024-07-11 16:45:45 +02:00
);
return contents ;
};
getMostRecentContentId = ( messageObject ) => {
const contents = Object . values ( messageObject . contentVersions );
return contents [ contents . length - 1 ]. id ;
2024-07-11 15:08:25 +02:00
};
2024-07-11 16:45:45 +02:00
getMostRecentContent = ( messageObject ) => {
const id = this . getMostRecentContentId ( messageObject );
return this . getObjectContentFromId ( messageObject , id );
2024-07-11 15:08:25 +02:00
};
2024-07-11 16:45:45 +02:00
getObjectContentFromId = ( messageObject , contentId ) => {
return messageObject . contentVersions [ contentId ];
2024-07-11 13:05:02 +02:00
};
2024-07-11 21:02:28 +02:00
getObjectTitle = ( messageObject ) => {
return messageObject . title || translation . untitledObject ;
};
2024-07-09 14:11:20 +02:00
// channel
2024-07-09 17:23:29 +02:00
setChannel = () => {
2024-07-09 14:11:20 +02:00
if ( this . cannotSetChannel . value == true ) return ;
2024-07-09 17:23:29 +02:00
this . primaryChannel . value = this . primaryChannelInput . value ;
UDN . subscribe ( this . primaryChannel . value );
2024-07-09 20:20:25 +02:00
updateMailbox ();
2024-07-09 17:23:29 +02:00
};
undoChannelChange = () => {
this . primaryChannelInput . value = this . primaryChannel . value ;
};
addSecondaryChannel = () => {
2024-07-09 14:11:20 +02:00
if ( this . cannotAddSecondaryChannel . value == true ) return ;
this . secondaryChannels . add ( this . newSecondaryChannelName . value );
this . newSecondaryChannelName . value = "" ;
2024-07-09 17:23:29 +02:00
};
removeSecondaryChannel = ( channel ) => {
2024-07-09 14:11:20 +02:00
this . secondaryChannels . remove ( channel );
2024-07-09 17:23:29 +02:00
};
2024-07-09 14:11:20 +02:00
};
2024-07-09 15:15:17 +02:00
function createChatWithName ( name ) {
const newChat = new Chat ();
chats . add ( newChat );
2024-07-09 17:23:29 +02:00
newChat . primaryChannel . value = name ;
2024-07-09 19:37:59 +02:00
newChat . primaryChannelInput . value = name ;
2024-07-09 17:23:29 +02:00
chatIds . add ( newChat . id );
UDN . subscribe ( name );
2024-07-09 20:20:25 +02:00
updateMailbox ();
2024-07-07 19:24:18 +02:00
}
2024-07-09 15:15:17 +02:00
// node_modules/udn-frontend/index.ts
var UDNFrontend = class {
ws ;
// HANDLERS
connectionHandler = () => {
};
disconnectionHandler = () => {
};
messageHandler = ( data ) => {
};
mailboxHandler = ( mailboxId2 ) => {
};
mailboxConnectionHandler = ( mailboxId2 ) => {
};
mailboxDeleteHandler = ( mailboxId2 ) => {
};
// INIT
set onconnect ( handler ) {
this . connectionHandler = handler ;
}
set ondisconnect ( handler ) {
this . disconnectionHandler = handler ;
}
set onmessage ( handler ) {
this . messageHandler = handler ;
}
set onmailboxcreate ( handler ) {
this . mailboxHandler = handler ;
}
set onmailboxconnect ( handler ) {
this . mailboxConnectionHandler = handler ;
}
set onmailboxdelete ( handler ) {
this . mailboxDeleteHandler = handler ;
}
// UTILITY METHODS
send ( messageObject ) {
if ( this . ws == void 0 ) return false ;
const messageString = JSON . stringify ( messageObject );
this . ws . send ( messageString );
return true ;
}
// PUBLIC METHODS
// connection
connect ( address ) {
try {
this . disconnect ();
this . ws = new WebSocket ( address );
this . ws . addEventListener ( "open" , this . connectionHandler );
this . ws . addEventListener ( "close" , this . disconnectionHandler );
this . ws . addEventListener ( "message" , ( message ) => {
const dataString = message . data . toString ();
const data = JSON . parse ( dataString );
if ( data . assignedMailboxId ) {
return this . mailboxHandler ( data . assignedMailboxId );
} else if ( data . connectedMailboxId ) {
return this . mailboxConnectionHandler ( data . connectedMailboxId );
} else if ( data . deletedMailbox ) {
return this . mailboxDeleteHandler ( data . deletedMailbox );
} else {
this . messageHandler ( data );
}
});
} catch ( error ) {
console . error ( error );
}
}
disconnect () {
this . ws ? . close ();
}
// message
sendMessage ( channel , body ) {
const messageObject = {
messageChannel : channel ,
messageBody : body
};
return this . send ( messageObject );
}
// subscription
subscribe ( channel ) {
const messageObject = {
subscribeChannel : channel
};
return this . send ( messageObject );
}
unsubscribe ( channel ) {
const messageObject = {
unsubscribeChannel : channel
};
return this . send ( messageObject );
}
// mailbox
requestMailbox () {
const messageObject = {
requestingMailboxSetup : true
};
return this . send ( messageObject );
}
connectMailbox ( mailboxId2 ) {
const messageObject = {
requestedMailbox : mailboxId2
};
return this . send ( messageObject );
}
deleteMailbox ( mailboxId2 ) {
const messageObject = {
deletingMailbox : mailboxId2
};
return this . send ( messageObject );
}
};
2024-07-11 20:16:28 +02:00
// src/Model/model.ts
var UDN = new UDNFrontend ();
var isConnected = new State ( false );
var serverAddressInput = restoreState ( "socket-address" , "" );
var didRequestConnection = restoreState (
"did-request-connection" ,
false
);
var currentAddress = restoreState ( "current-address" , "" );
var previousAddresses = restoreListState ( "previous-addresses" );
var cannotDisonnect = createProxyState (
[ isConnected ],
() => isConnected . value == false
);
var cannotConnect = createProxyState (
[ serverAddressInput , currentAddress , isConnected ],
() => serverAddressInput . value == "" || currentAddress . value == serverAddressInput . value && isConnected . value == true
);
var cannotResetAddress = createProxyState (
[ serverAddressInput , currentAddress ],
() => serverAddressInput . value == currentAddress . value
);
function connect () {
if ( cannotConnect . value == true ) return ;
2024-07-13 11:29:39 +02:00
serverAddressInput . value = serverAddressInput . value . toLowerCase ();
2024-07-11 20:16:28 +02:00
currentAddress . value = serverAddressInput . value ;
isConnected . value = false ;
didRequestConnection . value = true ;
UDN . connect ( serverAddressInput . value );
isMailboxActive . value = false ;
}
function disconnect () {
didRequestConnection . value = false ;
if ( cannotDisonnect . value == true ) return ;
UDN . disconnect ();
}
function resetAddressInput () {
serverAddressInput . value = currentAddress . value ;
}
function subscribeChannels () {
chats . value . forEach (( chat ) => {
UDN . subscribe ( chat . primaryChannel . value );
});
}
UDN . onconnect = () => {
isConnected . value = true ;
2024-07-13 11:29:39 +02:00
const lowerCasedAddress = currentAddress . value . toLowerCase ();
if ( ! previousAddresses . value . has ( lowerCasedAddress )) {
previousAddresses . add ( lowerCasedAddress );
2024-07-12 20:22:18 +02:00
}
2024-07-11 20:16:28 +02:00
subscribeChannels ();
if ( mailboxId . value != "" ) UDN . connectMailbox ( mailboxId . value );
};
UDN . onmessage = ( data ) => {
chats . value . forEach (( chat ) => {
chat . onmessage ( data );
});
};
UDN . ondisconnect = () => {
isConnected . value = false ;
};
var mailboxId = restoreState ( "mailbox-id" , "" );
var isMailboxActive = new State ( false );
var cannotDeleteMailbox = createProxyState (
[ mailboxId , isMailboxActive , isConnected ],
() => mailboxId . value == "" || isMailboxActive . value == false || isConnected . value == false
);
var cannotRequestMailbox = createProxyState (
[ isConnected , isMailboxActive ],
() => isConnected . value == false || isMailboxActive . value == true
);
function requestMailbox () {
if ( cannotRequestMailbox . value == true ) return ;
UDN . requestMailbox ();
}
function deleteMailbox () {
if ( cannotDeleteMailbox . value == true ) return ;
UDN . deleteMailbox ( mailboxId . value );
}
function updateMailbox () {
2024-07-11 20:25:54 +02:00
if ( isMailboxActive . value == false ) return ;
2024-07-11 20:16:28 +02:00
deleteMailbox ();
setTimeout (() => requestMailbox (), 10 );
}
UDN . onmailboxcreate = ( id ) => {
mailboxId . value = id ;
UDN . connectMailbox ( id );
};
UDN . onmailboxconnect = ( id ) => {
isMailboxActive . value = true ;
};
UDN . onmailboxdelete = () => {
isMailboxActive . value = false ;
mailboxId . value = "" ;
subscribeChannels ();
};
var outboxItemCount = new State ( 0 );
var outboxText = createProxyState (
[ outboxItemCount ],
() => translation . outboxText ( outboxItemCount . value )
);
var outboxTextStyle = createProxyState (
[ outboxItemCount ],
() => outboxItemCount . value == 0 ? "success" : "warning"
);
2024-07-12 21:11:33 +02:00
var isPresentingSettingsModal = new State ( false );
2024-07-11 20:16:28 +02:00
var isEncryptionAvailable = window . crypto . subtle != void 0 ;
var senderName = restoreState ( "sender-name" , "" );
var pageZoom = restoreState ( "page-zoom" , 100 );
pageZoom . subscribe (() => {
document . body . style . zoom = ` ${ pageZoom . value } %` ;
2024-07-13 12:16:35 +02:00
document . body . style . webkitTextSizeAdjust = ` ${ pageZoom . value } %` ;
2024-07-11 20:16:28 +02:00
});
2024-07-17 17:22:16 +00:00
var usedObjectCategories = restoreListState ( "object-categories" );
var usedObjectStatuses = restoreListState ( "object-statuses" );
var previousObjectSearches = restoreListState ( "object-searches" );
2024-07-12 21:11:33 +02:00
function toggleSettings () {
isPresentingSettingsModal . value = ! isPresentingSettingsModal . value ;
}
function repairApp () {
2024-07-13 11:41:01 +02:00
mapSetToLowercase ( previousAddresses );
2024-07-12 21:11:33 +02:00
removeSetDuplicates ( previousAddresses );
removeSetDuplicates ( usedObjectCategories );
removeSetDuplicates ( usedObjectStatuses );
2024-07-17 17:22:16 +00:00
removeSetDuplicates ( previousObjectSearches );
2024-07-12 21:11:33 +02:00
}
2024-07-13 11:41:01 +02:00
function mapSetToLowercase ( listState ) {
const lowerCased = [... listState . value ]. map (( x ) => x . toLowerCase ());
listState . clear ();
listState . add (... lowerCased );
}
2024-07-12 21:11:33 +02:00
function removeSetDuplicates ( listState ) {
2024-07-13 11:41:01 +02:00
const values = [... listState . value ];
listState . clear ();
listState . add (... values );
2024-07-12 21:11:33 +02:00
}
2024-07-12 22:26:59 +02:00
function clearAddresses () {
previousAddresses . clear ();
}
2024-07-12 22:24:54 +02:00
function clearCategories () {
usedObjectCategories . clear ();
}
function clearStatuses () {
usedObjectStatuses . clear ();
}
2024-07-17 17:22:16 +00:00
function clearObjectSearches () {
previousObjectSearches . clear ();
}
2024-07-11 20:16:28 +02:00
var zoomStep = 10 ;
function zoomOut () {
pageZoom . value -= zoomStep ;
}
function zoomIn () {
pageZoom . value += zoomStep ;
}
var chats = new ListState ();
var chatIds = restoreListState ( "chat-ids" );
var selectedChat = new State ( void 0 );
2024-07-11 21:34:21 +02:00
var isShowingObjects = restoreState ( "showing-objects" , false );
2024-07-13 15:10:54 +02:00
var isShowingChatInSplit = restoreState (
"showing-chat-split" ,
false
);
var isChatOpen = createProxyState (
[ selectedChat ],
() => selectedChat . value != void 0
);
var isChatVisible = createProxyState (
[ isShowingObjects , isShowingChatInSplit ],
() => isShowingObjects . value == false || isShowingChatInSplit . value == true
);
2024-07-13 16:30:29 +02:00
isShowingObjects . subscribeSilent (() => {
setTimeout (() => scrollToChat ( "instant" ), 1 );
});
2024-07-11 20:16:28 +02:00
var newChatName = new State ( "" );
var cannotCreateChat = createProxyState (
[ newChatName ],
() => newChatName . value == ""
);
function createChat () {
if ( cannotCreateChat . value == true ) return ;
createChatWithName ( newChatName . value );
newChatName . value = "" ;
}
function closeChatView () {
selectedChat . value = void 0 ;
document . getElementById ( "settings-tab" ) ? . scrollIntoView ();
}
function selectChat ( chat ) {
selectedChat . value = chat ;
chat . hasUnreadMessages . value = false ;
2024-07-13 16:30:29 +02:00
scrollToChat ();
}
function scrollToChat ( behavior = "smooth" ) {
document . getElementById ( "message-tab" ) ? . scrollIntoView ({ behavior });
2024-07-11 20:16:28 +02:00
}
2024-07-13 15:10:54 +02:00
function toggleObjects () {
2024-07-11 21:34:21 +02:00
isShowingObjects . value = ! isShowingObjects . value ;
2024-07-11 20:16:28 +02:00
}
2024-07-13 15:10:54 +02:00
function toggleChat () {
isShowingChatInSplit . value = ! isShowingChatInSplit . value ;
}
2024-07-11 20:16:28 +02:00
chatIds . value . forEach (( id ) => chats . add ( new Chat ( id )));
if ( serverAddressInput . value != "" && didRequestConnection . value == true ) {
connect ();
}
2024-07-12 00:43:58 +02:00
// src/Views/Chat/chatOptionModal.tsx
function ChatOptionModal ( chat , isPresented ) {
function closeModal () {
isPresented . value = false ;
}
function deleteChat () {
chat . deleteSelf ();
closeModal ();
closeChatView ();
}
const shouldShowKey = new State ( false );
const inputType = createProxyState (
[ shouldShowKey ],
() => shouldShowKey . value == true ? "text" : "password"
);
const secondaryChannelConverter = ( secondaryChannel ) => {
function remove () {
chat . removeSecondaryChannel ( secondaryChannel );
}
return /* @__PURE__ */ createElement ( "div" , { class : "tile width-input padding-0" }, /* @__PURE__ */ createElement ( "div" , { class : "flex-row justify-apart align-center" }, /* @__PURE__ */ createElement ( "b" , { class : "padding-h" }, secondaryChannel ), /* @__PURE__ */ createElement (
"button" ,
{
class : "danger" ,
"aria-label" : translation . removeSecondaryChannel ,
"on:click" : remove
},
/* @__PURE__ */ createElement ( "span" , { class : "icon" }, "delete" )
)));
};
return /* @__PURE__ */ createElement ( "div" , { class : "modal" , "toggle:open" : isPresented }, /* @__PURE__ */ createElement ( "div" , null , /* @__PURE__ */ createElement ( "main" , null , /* @__PURE__ */ createElement ( "h2" , null , translation . configureChatTitle ), /* @__PURE__ */ createElement ( "div" , null , /* @__PURE__ */ createElement ( "label" , { class : "tile" }, /* @__PURE__ */ createElement ( "span" , { class : "icon" }, "forum" ), /* @__PURE__ */ createElement ( "div" , null , /* @__PURE__ */ createElement ( "span" , null , translation . primaryChannel ), /* @__PURE__ */ createElement (
"input" ,
{
"bind:value" : chat . primaryChannelInput ,
placeholder : translation . primaryChannelPlaceholder ,
"on:enter" : chat . setChannel
}
))), /* @__PURE__ */ createElement ( "div" , { class : "flex-row width-input" }, /* @__PURE__ */ createElement (
"button" ,
{
"aria-label" : translation . undoChanges ,
class : "flex justify-center" ,
"on:click" : chat . undoChannelChange ,
"toggle:disabled" : chat . cannotUndoChannel
},
/* @__PURE__ */ createElement ( "span" , { class : "icon" }, "undo" )
), /* @__PURE__ */ createElement (
"button" ,
{
"aria-label" : translation . set ,
class : "flex justify-center primary" ,
"on:click" : chat . setChannel ,
"toggle:disabled" : chat . cannotSetChannel
},
/* @__PURE__ */ createElement ( "span" , { class : "icon" }, "check" )
))), /* @__PURE__ */ createElement ( "hr" , null ), /* @__PURE__ */ createElement ( "div" , { class : "flex-row margin-bottom width-input" }, /* @__PURE__ */ createElement (
"input" ,
{
"aria-label" : translation . secondaryChannel ,
placeholder : translation . secondaryChannelPlaceholder ,
"bind:value" : chat . newSecondaryChannelName ,
"on:enter" : chat . addSecondaryChannel
}
), /* @__PURE__ */ createElement (
"button" ,
{
class : "primary" ,
"toggle:disabled" : chat . cannotAddSecondaryChannel ,
"aria-label" : translation . addSecondaryChannel ,
"on:click" : chat . addSecondaryChannel
},
/* @__PURE__ */ createElement ( "span" , { class : "icon" }, "add" )
)), /* @__PURE__ */ createElement (
"div" ,
{
class : "flex-column gap" ,
"children:prepend" : [
chat . secondaryChannels ,
secondaryChannelConverter
]
}
), /* @__PURE__ */ createElement ( "hr" , null ), /* @__PURE__ */ createElement ( "div" , null , /* @__PURE__ */ createElement ( "label" , { class : "tile" }, /* @__PURE__ */ createElement ( "span" , { class : "icon" }, "key" ), /* @__PURE__ */ createElement ( "div" , null , /* @__PURE__ */ createElement ( "span" , null , translation . encryptionKey ), /* @__PURE__ */ createElement (
"input" ,
{
placeholder : translation . encryptionKeyPlaceholder ,
"bind:value" : chat . encryptionKey ,
"set:type" : inputType
}
))), /* @__PURE__ */ createElement ( "label" , { class : "inline margin-0" }, /* @__PURE__ */ createElement ( "input" , { type : "checkbox" , "bind:checked" : shouldShowKey }), translation . showKey )), /* @__PURE__ */ createElement ( "hr" , null ), /* @__PURE__ */ createElement ( "div" , { class : "flex-column gap width-input" }, /* @__PURE__ */ createElement ( "button" , { "on:click" : chat . resendObjects }, translation . resendObjects , /* @__PURE__ */ createElement ( "span" , { class : "icon" }, "replay" ))), /* @__PURE__ */ createElement ( "hr" , null ), /* @__PURE__ */ createElement ( "div" , { class : "flex-column gap width-input" }, /* @__PURE__ */ createElement (
"button" ,
{
class : "danger" ,
"on:click" : chat . clearObjects ,
"toggle:disabled" : chat . cannotClearObjects
},
translation . clearObjects ,
/* @__PURE__ */ createElement ( "span" , { class : "icon" }, "deployed_code" )
), /* @__PURE__ */ createElement (
"button" ,
{
class : "danger" ,
"on:click" : chat . clearMessages ,
"toggle:disabled" : chat . cannotClearMessages
},
translation . clearChatMessages ,
/* @__PURE__ */ createElement ( "span" , { class : "icon" }, "chat_error" )
), /* @__PURE__ */ createElement ( "button" , { class : "danger" , "on:click" : deleteChat }, translation . removeChat , /* @__PURE__ */ createElement ( "span" , { class : "icon" }, "delete_forever" )))), /* @__PURE__ */ createElement ( "button" , { "on:click" : closeModal }, translation . close , /* @__PURE__ */ createElement ( "span" , { class : "icon" }, "close" ))));
}
// src/Views/Chat/messageComposer.tsx
function MessageComposer ( chat ) {
return /* @__PURE__ */ createElement ( "div" , { class : "flex-row width-100" }, " " , /* @__PURE__ */ createElement (
"input" ,
{
class : "width-100 flex-1" ,
style : "max-width: unset" ,
placeholder : translation . composerPlaceholder ,
"bind:value" : chat . composingMessage ,
"on:enter" : chat . sendMessageFromComposer
}
), /* @__PURE__ */ createElement (
"button" ,
{
class : "primary" ,
"on:click" : chat . sendMessageFromComposer ,
"toggle:disabled" : chat . cannotSendMessage
},
/* @__PURE__ */ createElement ( "span" , { class : "icon" }, "send" )
));
}
2024-07-11 22:27:15 +02:00
// src/icons.ts
var icons = {
objectTitle : "label" ,
objectHistory : "history" ,
noteContent : "sticky_note_2" ,
categoryName : "category" ,
2024-07-12 14:30:30 +02:00
status : "trending_up" ,
2024-07-11 22:27:15 +02:00
priority : "priority_high" ,
date : "calendar_month" ,
time : "schedule"
};
// src/Views/Objects/objectEntryView.tsx
function ObjectEntryView ( chat , messageObject , selectedObject , isShowingObjectModal ) {
const latest = chat . getMostRecentContent ( messageObject );
function select () {
selectedObject . value = messageObject ;
isShowingObjectModal . value = true ;
}
2024-07-12 01:05:00 +02:00
function dragStart ( event ) {
event . dataTransfer ? . setData ( "text" , messageObject . id );
}
2024-07-11 22:27:15 +02:00
const fields = {
[ icons . noteContent ] : "---" ,
[ icons . priority ] : "---" ,
2024-07-12 15:45:26 +02:00
[ icons . categoryName ] : "---" ,
2024-07-12 14:30:30 +02:00
[ icons . status ] : "---" ,
2024-07-11 22:27:15 +02:00
[ icons . date ] : "---" ,
[ icons . time ] : "---"
};
Object . entries ( latest ). forEach (( entry ) => {
let [ key , value ] = entry ;
if ( ! value ) return ;
const icon = icons [ key ];
if ( ! icon ) return ;
2024-07-12 14:30:30 +02:00
if ( ! fields [ icon ]) return ;
2024-07-11 22:27:15 +02:00
fields [ icon ] = value ;
});
const fieldElements = Object . entries ( fields ). map (( field ) => {
const [ icon , value ] = field ;
2024-07-12 15:45:26 +02:00
return /* @__PURE__ */ createElement ( "span" , { class : "flex-row control-gap flex align-center padding-right ellipsis" }, /* @__PURE__ */ createElement ( "span" , { class : "icon" }, icon ), /* @__PURE__ */ createElement ( "span" , { class : "ellipsis" }, value ));
2024-07-11 22:27:15 +02:00
});
2024-07-12 01:05:00 +02:00
return /* @__PURE__ */ createElement (
"button" ,
{
2024-07-12 01:42:39 +02:00
class : "tile flex-no" ,
2024-07-12 01:05:00 +02:00
"on:click" : select ,
draggable : "true" ,
"on:dragstart" : dragStart
},
2024-07-12 15:45:26 +02:00
/* @__PURE__ */ createElement ( "div" , null , /* @__PURE__ */ createElement ( "b" , { class : "ellipsis" }, chat . getObjectTitle ( messageObject )), /* @__PURE__ */ createElement ( "hr" , null ), /* @__PURE__ */ createElement (
"span" ,
{
class : "grid height-100 flex secondary" ,
2024-07-17 14:25:11 +00:00
style : "grid-template-columns: 1fr 1fr; grid-template-rows: repeat(3, 1.7rem)"
2024-07-12 15:45:26 +02:00
},
... fieldElements
))
2024-07-12 01:05:00 +02:00
);
2024-07-11 22:27:15 +02:00
}
2024-07-11 22:35:46 +02:00
// src/Views/Objects/objectGridView.tsx
2024-07-12 01:19:16 +02:00
function ObjectGridView ( chat , messageObjects , selectedObject , isShowingObjectModal ) {
2024-07-11 18:54:56 +02:00
const objectConverter = ( messageObject ) => {
2024-07-11 22:27:15 +02:00
return ObjectEntryView (
chat ,
messageObject ,
selectedObject ,
isShowingObjectModal
);
2024-07-11 18:54:56 +02:00
};
2024-07-12 19:04:57 +02:00
return /* @__PURE__ */ createElement (
2024-07-11 22:35:46 +02:00
"div" ,
{
2024-07-15 22:04:29 +02:00
class : "grid gap" ,
2024-07-12 15:45:26 +02:00
style : "grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));" ,
2024-07-11 22:35:46 +02:00
"children:prepend" : [ messageObjects , objectConverter ]
}
);
}
// src/Views/Objects/allObjectsView.tsx
2024-07-13 17:13:59 +02:00
function AllObjectsView ( chat , messageObjects , selectedObject , isShowingObjectModal ) {
2024-07-12 20:40:03 +02:00
const objectCount = createProxyState (
[ chat . objects ],
() => chat . objects . value . size
);
2024-07-15 22:04:29 +02:00
return /* @__PURE__ */ createElement ( "div" , { class : "width-100 height-100 scroll-v padding flex-column gap" }, /* @__PURE__ */ createElement ( "b" , { class : "secondary" }, translation . objectsInTotal , " " , /* @__PURE__ */ createElement ( "span" , { "subscribe:innerText" : objectCount })), ObjectGridView (
2024-07-13 17:13:59 +02:00
chat ,
messageObjects ,
selectedObject ,
isShowingObjectModal
));
2024-07-11 18:54:56 +02:00
}
2024-07-12 14:30:30 +02:00
// src/Views/renameView.tsx
function RenameView ( editingName , initialName , rename ) {
const cannotRename = createProxyState (
[ editingName ],
() => editingName . value == initialName || editingName . value == ""
);
return /* @__PURE__ */ createElement ( "div" , { class : "flex-row align-center justify-apart object-entry-wide" }, /* @__PURE__ */ createElement ( "input" , { "bind:value" : editingName , "on:enter" : rename }), /* @__PURE__ */ createElement (
"button" ,
{
class : "primary" ,
"aria-label" : translation . rename ,
"on:click" : rename ,
"toggle:disabled" : cannotRename
},
/* @__PURE__ */ createElement ( "span" , { class : "icon" }, "edit" )
));
}
2024-07-12 00:43:58 +02:00
// src/Views/Objects/kanbanView.tsx
2024-07-13 17:13:59 +02:00
function KanbanView ( chat , messageObjects , selectedObject , isShowingObjectModal ) {
2024-07-12 00:43:58 +02:00
const boards = new MapState ();
2024-07-12 19:04:57 +02:00
const sortedBoardNames = createProxyState (
[ boards ],
() => [... boards . value . values ()]. map (( board ) => board . category ). sort (( a , b ) => a . localeCompare ( b ))
);
2024-07-13 17:13:59 +02:00
messageObjects . handleAddition (( messageObject ) => {
2024-07-12 19:04:57 +02:00
const latest = chat . getMostRecentContent ( messageObject );
if ( ! latest ) return ;
if ( ! latest . categoryName ) return ;
const categoryName = latest . categoryName ;
if ( ! boards . value . has ( categoryName )) {
const listState = new ListState ();
listState . subscribeSilent (() => {
if ( listState . value . size != 0 ) return ;
boards . remove ( categoryName );
});
boards . set ( categoryName , {
category : categoryName ,
items : listState
2024-07-12 02:02:49 +02:00
});
2024-07-12 19:04:57 +02:00
}
const boardItem = {
priority : latest . priority ?? 0 ,
messageObject
};
boards . value . get ( categoryName ) ? . items . add ( boardItem );
2024-07-13 17:13:59 +02:00
messageObjects . handleRemoval ( messageObject , () => {
2024-07-12 19:04:57 +02:00
boards . value . get ( categoryName ) ? . items . remove ( boardItem );
2024-07-12 00:43:58 +02:00
});
});
2024-07-12 19:04:57 +02:00
const boardToBoardView = ( board ) => {
const view = KanbanBoardView (
chat ,
board ,
selectedObject ,
isShowingObjectModal
);
sortedBoardNames . subscribe (( sortedBoardNames2 ) => {
view . style . order = sortedBoardNames2 . indexOf ( board . category );
});
return view ;
};
return /* @__PURE__ */ createElement (
"div" ,
{
class : "flex-row large-gap width-100 height-100 scroll-v scroll-h padding" ,
"children:append" : [ boards , boardToBoardView ]
}
2024-07-12 01:19:16 +02:00
);
2024-07-12 00:43:58 +02:00
}
function KanbanBoardView ( chat , kanbanBoard , selectedObject , isShowingObjectModal ) {
2024-07-12 14:30:30 +02:00
const editingCategory = new State ( kanbanBoard . category );
2024-07-12 01:54:53 +02:00
function renameBoard () {
2024-07-12 19:04:57 +02:00
kanbanBoard . items . value . forEach (( kanbanBoardItem ) => {
2024-07-12 02:02:49 +02:00
const { messageObject } = kanbanBoardItem ;
2024-07-12 01:54:53 +02:00
const latest = chat . getMostRecentContent ( messageObject );
2024-07-12 14:30:30 +02:00
latest . categoryName = editingCategory . value ;
2024-07-12 01:54:53 +02:00
chat . addObjectAndSend ( messageObject );
});
}
2024-07-12 01:05:00 +02:00
function dragOver ( event ) {
event . preventDefault ();
}
function drop ( event ) {
event . preventDefault ();
var id = event . dataTransfer ? . getData ( "text" );
if ( ! id ) return ;
const messageObject = chat . objects . value . get ( id );
if ( ! messageObject ) return ;
2024-07-13 11:56:15 +02:00
const newContent = chat . createObjectContent ();
newContent . categoryName = kanbanBoard . category ;
chat . updateObjectContent ( messageObject , newContent );
2024-07-12 01:05:00 +02:00
chat . addObjectAndSend ( messageObject );
}
2024-07-12 19:04:57 +02:00
const itemToViewEntry = ( kanbanBoardItem ) => {
const view = ObjectEntryView (
chat ,
kanbanBoardItem . messageObject ,
selectedObject ,
isShowingObjectModal
);
view . style . order = kanbanBoardItem . priority * - 1 ;
return view ;
};
2024-07-12 01:05:00 +02:00
return /* @__PURE__ */ createElement (
"div" ,
{
2024-07-12 14:30:30 +02:00
class : "flex-column flex-no object-entry-wide" ,
2024-07-12 01:05:00 +02:00
"on:dragover" : dragOver ,
"on:drop" : drop
},
2024-07-12 14:30:30 +02:00
RenameView ( editingCategory , kanbanBoard . category , renameBoard ),
2024-07-12 01:05:00 +02:00
/* @__PURE__ */ createElement ( "hr" , null ),
2024-07-12 19:04:57 +02:00
/* @__PURE__ */ createElement (
"div" ,
{
class : "flex-column gap padding-bottom" ,
"children:append" : [ kanbanBoard . items , itemToViewEntry ]
}
)
2024-07-12 01:05:00 +02:00
);
2024-07-12 00:43:58 +02:00
}
2024-07-11 18:54:56 +02:00
// src/Views/Objects/noteObjectsView.tsx
2024-07-13 17:13:59 +02:00
function NoteObjectsView ( chat , messageObjects , selectedObject , isShowingObjectModal ) {
2024-07-11 19:29:12 +02:00
const notes = new ListState ();
2024-07-13 17:13:59 +02:00
messageObjects . handleAddition (( messageObject ) => {
2024-07-12 19:04:57 +02:00
const latest = chat . getMostRecentContent ( messageObject );
if ( ! latest ) return ;
if ( ! latest . noteContent ) return ;
notes . add ( messageObject );
2024-07-13 17:13:59 +02:00
messageObjects . handleRemoval (
2024-07-12 19:04:57 +02:00
messageObject ,
() => notes . remove ( messageObject )
);
2024-07-11 19:29:12 +02:00
});
2024-07-15 22:04:29 +02:00
return /* @__PURE__ */ createElement ( "div" , { class : "width-100 height-100 scroll-v padding" }, ObjectGridView ( chat , notes , selectedObject , isShowingObjectModal ));
2024-07-11 18:54:56 +02:00
}
2024-07-11 17:07:06 +02:00
// src/Views/Objects/objectDetailModal.tsx
function ObjectDetailModal ( chat , messageObject , isPresented ) {
const editingTitle = new State ( messageObject . title );
const selectedMessageObjectId = new State (
chat . getMostRecentContentId ( messageObject )
);
const selectedMessageObject = createProxyState (
[ selectedMessageObjectId ],
() => chat . getObjectContentFromId ( messageObject , selectedMessageObjectId . value )
);
const didEditContent = new State ( false );
const editingNoteContent = createProxyState (
[ selectedMessageObject ],
() => selectedMessageObject . value . noteContent ?? ""
);
2024-07-11 21:30:57 +02:00
const editingCategory = createProxyState (
[ selectedMessageObject ],
() => selectedMessageObject . value . categoryName ?? ""
);
2024-07-12 14:30:30 +02:00
const editingStatus = createProxyState (
[ selectedMessageObject ],
() => selectedMessageObject . value . status ?? ""
);
2024-07-11 21:30:57 +02:00
const editingDate = createProxyState (
[ selectedMessageObject ],
2024-07-11 22:27:15 +02:00
() => selectedMessageObject . value . date ?? ""
2024-07-11 21:30:57 +02:00
);
const editingTime = createProxyState (
[ selectedMessageObject ],
2024-07-11 22:27:15 +02:00
() => selectedMessageObject . value . time ?? ""
2024-07-11 21:30:57 +02:00
);
const editingPriority = createProxyState (
[ selectedMessageObject ],
() => selectedMessageObject . value . priority ?? 0
);
2024-07-11 17:07:06 +02:00
bulkSubscribe (
2024-07-11 22:27:15 +02:00
[
editingNoteContent ,
editingCategory ,
2024-07-12 14:30:30 +02:00
editingStatus ,
2024-07-11 22:27:15 +02:00
editingDate ,
editingTime ,
editingPriority
],
2024-07-11 17:07:06 +02:00
() => didEditContent . value = true
);
function handleKeyDown ( e ) {
if ( ! e . metaKey && ! e . ctrlKey ) return ;
switch ( e . key ) {
case "s" :
e . preventDefault ();
saveAndClose ();
break ;
}
}
function closeModal () {
isPresented . value = false ;
}
function saveAndClose () {
messageObject . title = editingTitle . value ;
if ( didEditContent . value == true ) {
chat . addObjectContent ( messageObject , {
isoDateVersionCreated : ( /* @__PURE__ */ new Date ()). toISOString (),
id : UUID (),
2024-07-11 21:30:57 +02:00
noteContent : editingNoteContent . value ,
priority : editingPriority . value ,
categoryName : editingCategory . value ,
2024-07-12 14:30:30 +02:00
status : editingStatus . value ,
2024-07-11 22:27:15 +02:00
date : editingDate . value ,
time : editingTime . value
2024-07-11 17:07:06 +02:00
});
}
chat . addObjectAndSend ( messageObject );
closeModal ();
}
function deleteAndClose () {
chat . deleteObject ( messageObject );
closeModal ();
}
2024-07-11 21:02:28 +02:00
const input = /* @__PURE__ */ createElement (
2024-07-11 17:07:06 +02:00
"input" ,
{
"bind:value" : editingTitle ,
placeholder : translation . objectTitlePlaceholder
}
2024-07-11 21:02:28 +02:00
);
isPresented . subscribe (() => setTimeout (() => input . focus (), 100 ));
2024-07-11 22:27:15 +02:00
return /* @__PURE__ */ createElement ( "div" , { class : "modal" , "toggle:open" : isPresented , "on:keydown" : handleKeyDown }, /* @__PURE__ */ createElement ( "div" , null , /* @__PURE__ */ createElement ( "main" , null , /* @__PURE__ */ createElement ( "h2" , null , chat . getObjectTitle ( messageObject )), /* @__PURE__ */ createElement ( "span" , { class : "secondary" }, messageObject . id ), /* @__PURE__ */ createElement ( "hr" , null ), /* @__PURE__ */ createElement ( "div" , { class : "flex-column gap" }, /* @__PURE__ */ createElement ( "label" , { class : "tile" }, /* @__PURE__ */ createElement ( "span" , { class : "icon" }, icons . objectTitle ), /* @__PURE__ */ createElement ( "div" , null , /* @__PURE__ */ createElement ( "span" , null , translation . objectTitle ), input )), /* @__PURE__ */ createElement ( "hr" , null ), /* @__PURE__ */ createElement ( "label" , { class : "tile" }, /* @__PURE__ */ createElement ( "span" , { class : "icon" }, icons . objectHistory ), /* @__PURE__ */ createElement ( "div" , null , /* @__PURE__ */ createElement ( "span" , null , translation . objectVersion ), /* @__PURE__ */ createElement ( "select" , { "bind:value" : selectedMessageObjectId }, ... chat . getSortedContents ( messageObject ). map (( content ) => /* @__PURE__ */ createElement ( "option" , { value : content . id }, new Date (
2024-07-11 17:07:06 +02:00
content . isoDateVersionCreated
2024-07-11 22:27:15 +02:00
). toLocaleString ()))), /* @__PURE__ */ createElement ( "span" , { class : "icon" }, "arrow_drop_down" ))), /* @__PURE__ */ createElement ( "hr" , null ), /* @__PURE__ */ createElement ( "label" , { class : "tile" }, /* @__PURE__ */ createElement ( "span" , { class : "icon" }, icons . noteContent ), /* @__PURE__ */ createElement ( "div" , null , /* @__PURE__ */ createElement ( "span" , null , translation . note ), /* @__PURE__ */ createElement (
2024-07-11 17:07:06 +02:00
"textarea" ,
{
2024-07-12 14:30:30 +02:00
rows : "10" ,
2024-07-12 02:24:48 +02:00
class : "height-auto" ,
2024-07-11 17:07:06 +02:00
"bind:value" : editingNoteContent ,
placeholder : translation . noteContentPlaceholder
}
2024-07-12 14:30:30 +02:00
))), /* @__PURE__ */ createElement ( "hr" , null ), /* @__PURE__ */ createElement ( "label" , { class : "tile" }, /* @__PURE__ */ createElement ( "span" , { class : "icon" }, icons . categoryName ), /* @__PURE__ */ createElement ( "div" , null , /* @__PURE__ */ createElement ( "span" , null , translation . category ), /* @__PURE__ */ createElement (
2024-07-11 21:30:57 +02:00
"input" ,
{
"bind:value" : editingCategory ,
2024-07-12 02:24:48 +02:00
placeholder : translation . categoryPlaceholder ,
list : "object-categories"
}
))), /* @__PURE__ */ createElement (
"datalist" ,
{
hidden : true ,
id : "object-categories" ,
"children:append" : [ usedObjectCategories , stringToOptionTag ]
2024-07-11 21:30:57 +02:00
}
2024-07-12 02:24:48 +02:00
), /* @__PURE__ */ createElement ( "label" , { class : "tile" }, /* @__PURE__ */ createElement ( "span" , { class : "icon" }, icons . priority ), /* @__PURE__ */ createElement ( "div" , null , /* @__PURE__ */ createElement ( "span" , null , translation . priority ), /* @__PURE__ */ createElement (
2024-07-11 21:30:57 +02:00
"input" ,
{
type : "number" ,
"bind:value" : editingPriority ,
placeholder : translation . priorityPlaceholder
}
2024-07-12 14:30:30 +02:00
))), /* @__PURE__ */ createElement ( "label" , { class : "tile" }, /* @__PURE__ */ createElement ( "span" , { class : "icon" }, icons . status ), /* @__PURE__ */ createElement ( "div" , null , /* @__PURE__ */ createElement ( "span" , null , translation . status ), /* @__PURE__ */ createElement (
"input" ,
{
"bind:value" : editingStatus ,
2024-07-12 15:09:57 +02:00
placeholder : translation . statusPlaceholder ,
list : "object-statuses"
2024-07-12 14:30:30 +02:00
}
2024-07-12 15:09:57 +02:00
))), /* @__PURE__ */ createElement (
"datalist" ,
{
hidden : true ,
id : "object-statuses" ,
"children:append" : [ usedObjectStatuses , stringToOptionTag ]
}
), /* @__PURE__ */ createElement ( "hr" , null ), /* @__PURE__ */ createElement ( "label" , { class : "tile" }, /* @__PURE__ */ createElement ( "span" , { class : "icon" }, icons . date ), /* @__PURE__ */ createElement ( "div" , null , /* @__PURE__ */ createElement ( "span" , null , translation . date ), /* @__PURE__ */ createElement ( "input" , { type : "date" , "bind:value" : editingDate }))), /* @__PURE__ */ createElement ( "label" , { class : "tile" }, /* @__PURE__ */ createElement ( "span" , { class : "icon" }, icons . time ), /* @__PURE__ */ createElement ( "div" , null , /* @__PURE__ */ createElement ( "span" , null , translation . time ), /* @__PURE__ */ createElement ( "input" , { type : "time" , "bind:value" : editingTime }))), /* @__PURE__ */ createElement ( "hr" , null ), /* @__PURE__ */ createElement ( "button" , { class : "danger width-input" , "on:click" : deleteAndClose }, translation . deleteObject , /* @__PURE__ */ createElement ( "span" , { class : "icon" }, "delete" )))), /* @__PURE__ */ createElement ( "div" , { class : "flex-row" }, /* @__PURE__ */ createElement ( "button" , { class : "flex-1 width-100 danger" , "on:click" : closeModal }, translation . discard ), /* @__PURE__ */ createElement ( "button" , { class : "flex-1 width-100 primary" , "on:click" : saveAndClose }, translation . save , /* @__PURE__ */ createElement ( "span" , { class : "icon" }, "save" )))));
2024-07-11 17:07:06 +02:00
}
2024-07-12 14:30:30 +02:00
// src/Views/Objects/statusView.tsx
2024-07-13 17:13:59 +02:00
function StatusView ( chat , messageObjects , selectedObject , isShowingObjectModal ) {
2024-07-12 14:30:30 +02:00
const rows = new MapState ();
2024-07-12 19:04:57 +02:00
const statuses = new MapState ();
const sortedStatuses = createProxyState (
[ statuses ],
() => [... statuses . value . values ()]. map (( statusData ) => statusData . title ). sort (( a , b ) => a . localeCompare ( b ))
);
const sortedCategoryNames = createProxyState (
[ rows ],
() => [... rows . value . values ()]. map (( row ) => row . category ). sort (( a , b ) => a . localeCompare ( b ))
);
2024-07-13 17:13:59 +02:00
messageObjects . subscribe (() => {
2024-07-12 14:30:30 +02:00
rows . clear ();
statuses . clear ();
2024-07-13 17:13:59 +02:00
messageObjects . value . forEach (( messageObject ) => {
2024-07-12 14:30:30 +02:00
const latest = chat . getMostRecentContent ( messageObject );
if ( ! latest . categoryName || ! latest . status ) return ;
const category = latest . categoryName ;
const status = latest . status ;
2024-07-12 19:04:57 +02:00
if ( ! statuses . value . has ( status )) {
2024-07-12 14:30:30 +02:00
statuses . set ( status , { title : status , items : [] });
}
2024-07-12 19:04:57 +02:00
statuses . value . get ( status ). items . push ( messageObject );
2024-07-12 14:30:30 +02:00
if ( ! rows . value . has ( category )) {
2024-07-12 19:04:57 +02:00
rows . set ( category , {
category ,
statusColumns : new MapState ()
});
2024-07-12 14:30:30 +02:00
}
const row = rows . value . get ( category );
2024-07-12 19:04:57 +02:00
if ( ! row . statusColumns . value . has ( status )) {
row . statusColumns . set ( status , {
status ,
items : new ListState ()
});
2024-07-12 14:30:30 +02:00
}
2024-07-12 19:04:57 +02:00
const column = row . statusColumns . value . get ( status );
column . items . add ({
2024-07-12 14:30:30 +02:00
priority : latest . priority ?? 0 ,
status ,
messageObject
});
});
2024-07-12 19:04:57 +02:00
statuses . value . forEach (( statusItemList ) => {
2024-07-12 14:30:30 +02:00
rows . value . forEach (( row ) => {
2024-07-12 19:04:57 +02:00
if ( row . statusColumns . value . has ( statusItemList . title )) return ;
2024-07-12 14:30:30 +02:00
row . statusColumns . set ( statusItemList . title , {
2024-07-12 19:04:57 +02:00
status : statusItemList . title ,
items : new ListState ()
2024-07-12 14:30:30 +02:00
});
});
});
});
2024-07-12 19:04:57 +02:00
const statusDataToHeaderView = ( statusData ) => {
const view = StatusHeaderView ( chat , statusData );
sortedStatuses . subscribe (
() => view . style . order = sortedStatuses . value . indexOf ( statusData . title )
);
return view ;
};
const categoryRowToView = ( row ) => {
const view = KanbanRowView (
chat ,
row ,
sortedStatuses ,
selectedObject ,
isShowingObjectModal
);
sortedCategoryNames . subscribe (
() => view . style . order = sortedCategoryNames . value . indexOf ( row . category )
);
return view ;
};
return /* @__PURE__ */ createElement ( "div" , { class : "flex-column large-gap width-100 height-100 scroll-v scroll-h padding" }, /* @__PURE__ */ createElement ( "div" , { class : "flex-row large-gap" }, /* @__PURE__ */ createElement ( "div" , { class : "flex-column object-entry-wide" }), /* @__PURE__ */ createElement (
"div" ,
{
class : "flex-row large-gap" ,
"children:append" : [ statuses , statusDataToHeaderView ]
}
)), /* @__PURE__ */ createElement (
"div" ,
{
class : "flex-column large-gap" ,
"children:append" : [ rows , categoryRowToView ]
}
));
2024-07-12 14:30:30 +02:00
}
function StatusHeaderView ( chat , status ) {
const editingStatus = new State ( status . title );
function rename () {
status . items . forEach (( messageObject ) => {
const latest = chat . getMostRecentContent ( messageObject );
if ( ! latest ) return ;
latest . status = editingStatus . value ;
chat . addObject ( messageObject );
});
}
return /* @__PURE__ */ createElement ( "div" , { class : "object-entry-wide" }, RenameView ( editingStatus , status . title , rename ), /* @__PURE__ */ createElement ( "hr" , null ));
}
2024-07-12 19:04:57 +02:00
function KanbanRowView ( chat , kanbanRow , sortedStatuses , selectedObject , isShowingObjectModal ) {
2024-07-12 14:30:30 +02:00
const editingCategory = new State ( kanbanRow . category );
function renameCategory () {
2024-07-12 19:04:57 +02:00
kanbanRow . statusColumns . value . forEach (( statusColumns ) => {
statusColumns . items . value . forEach (( statusCellItem ) => {
2024-07-12 14:30:30 +02:00
const { messageObject } = statusCellItem ;
const latest = chat . getMostRecentContent ( messageObject );
latest . categoryName = editingCategory . value ;
chat . addObjectAndSend ( messageObject );
});
});
}
2024-07-12 19:04:57 +02:00
const statusColumnToEntryView = ( statusColumn ) => {
const view = StatusColumnView (
2024-07-12 14:30:30 +02:00
chat ,
2024-07-12 19:04:57 +02:00
statusColumn . items ,
2024-07-12 14:30:30 +02:00
kanbanRow . category ,
2024-07-12 19:04:57 +02:00
statusColumn . status ,
2024-07-12 14:30:30 +02:00
selectedObject ,
isShowingObjectModal
2024-07-12 19:04:57 +02:00
);
sortedStatuses . subscribe (
() => view . style . order = sortedStatuses . value . indexOf ( statusColumn . status )
);
return view ;
};
return /* @__PURE__ */ createElement ( "div" , { class : "flex-row flex-no large-gap" }, /* @__PURE__ */ createElement ( "div" , { class : "flex-row align-start" }, RenameView ( editingCategory , kanbanRow . category , renameCategory )), /* @__PURE__ */ createElement (
"div" ,
{
class : "flex-row large-gap" ,
"children:append" : [ kanbanRow . statusColumns , statusColumnToEntryView ]
}
));
2024-07-12 14:30:30 +02:00
}
function StatusColumnView ( chat , items , category , status , selectedObject , isShowingObjectModal ) {
function dragOver ( event ) {
event . preventDefault ();
}
function drop ( event ) {
event . preventDefault ();
var id = event . dataTransfer ? . getData ( "text" );
if ( ! id ) return ;
const messageObject = chat . objects . value . get ( id );
if ( ! messageObject ) return ;
2024-07-13 11:56:15 +02:00
const newContent = chat . createObjectContent ();
newContent . categoryName = category ;
newContent . status = status ;
chat . updateObjectContent ( messageObject , newContent );
2024-07-12 14:30:30 +02:00
chat . addObjectAndSend ( messageObject );
}
2024-07-12 19:04:57 +02:00
const cellItemToEntryView = ( cellItem ) => ObjectEntryView (
chat ,
cellItem . messageObject ,
selectedObject ,
isShowingObjectModal
);
2024-07-12 14:30:30 +02:00
return /* @__PURE__ */ createElement (
"div" ,
{
class : "flex-column gap object-entry-wide" ,
"on:dragover" : dragOver ,
2024-07-12 19:04:57 +02:00
"on:drop" : drop ,
"children:append" : [ items , cellItemToEntryView ]
}
2024-07-12 14:30:30 +02:00
);
}
2024-07-12 00:43:58 +02:00
// src/Views/Objects/objectPane.tsx
2024-07-11 18:54:56 +02:00
var viewTypes = {
all : [ translation . viewAll , "grid_view" ],
2024-07-12 00:43:58 +02:00
notes : [ translation . viewNotes , icons . noteContent ],
2024-07-12 14:30:30 +02:00
kanban : [ translation . viewKanban , "view_kanban" ],
status : [ translation . viewStatus , icons . status ]
2024-07-11 18:54:56 +02:00
};
2024-07-12 00:43:58 +02:00
function ObjectPane ( chat ) {
2024-07-11 17:07:06 +02:00
const isShowingObjectModal = new State ( false );
2024-07-13 17:13:59 +02:00
const isShowingFilterModel = new State ( false );
2024-07-11 17:07:06 +02:00
const selectedObject = new State ( void 0 );
2024-07-13 17:13:59 +02:00
function createObject () {
const newObject = chat . createObjectFromTitle ( "" );
chat . addObjectAndSend ( newObject );
selectedObject . value = newObject ;
isShowingObjectModal . value = true ;
}
function showFilters () {
isShowingFilterModel . value = true ;
}
function closeFilters () {
isShowingFilterModel . value = false ;
}
const filterInput = new State ( "" );
const appliedFilter = new State ( "" );
const resultCount = new State ( 0 );
const resultText = createProxyState (
[ appliedFilter , resultCount ],
() => translation . searchTitleText ( appliedFilter . value , resultCount . value )
);
2024-07-15 21:58:32 +02:00
const showingMessageObjects = new MapState ();
2024-07-17 14:25:11 +00:00
const isFilterEmpty = createProxyState (
2024-07-13 17:13:59 +02:00
[ appliedFilter ],
() => appliedFilter . value == ""
);
function resetFilter () {
filterInput . value = "" ;
applyFilter ();
}
function applyFilter () {
appliedFilter . value = filterInput . value ;
2024-07-17 17:22:16 +00:00
previousObjectSearches . add ( appliedFilter . value );
2024-07-17 15:48:04 +00:00
const allObjects = [... chat . objects . value . values ()];
allObjects . forEach (( object , i ) => {
const doesMatch = checkIfMatchesFilter ( object );
if ( doesMatch ) {
showingMessageObjects . set ( object . id , object );
} else {
showingMessageObjects . remove ( object . id );
}
2024-07-15 17:15:52 +02:00
});
2024-07-17 15:48:04 +00:00
resultCount . value = showingMessageObjects . value . size ;
2024-07-15 21:58:32 +02:00
}
chat . objects . handleAddition (( messageObject ) => {
2024-07-17 15:48:04 +00:00
if ( checkIfMatchesFilter ( messageObject ) == false ) return ;
2024-07-15 21:58:32 +02:00
showingMessageObjects . set ( messageObject . id , messageObject );
chat . objects . handleRemoval ( messageObject , () => {
showingMessageObjects . remove ( messageObject . id );
});
});
2024-07-17 15:48:04 +00:00
function checkIfMatchesFilter ( messageObject ) {
2024-07-17 14:25:11 +00:00
if ( isFilterEmpty . value == true ) return true ;
2024-07-17 15:48:04 +00:00
const stringsInObject = [];
2024-07-17 14:25:11 +00:00
const objectTitle = messageObject . title || translation . untitledObject ;
2024-07-17 15:48:04 +00:00
stringsInObject . push ( objectTitle );
2024-07-17 14:25:11 +00:00
const latest = chat . getMostRecentContent ( messageObject );
if ( latest ) {
Object . values ( latest ). forEach (( value ) => {
2024-07-17 15:48:04 +00:00
if ( typeof value != "string" ) return ;
stringsInObject . push ( value );
2024-07-17 14:25:11 +00:00
});
}
2024-07-17 15:48:04 +00:00
const wordsOfObject = stringsInObject . map (( string ) => string . toLowerCase (). split ( " " )). flat ();
2024-07-17 14:25:11 +00:00
const wordsOfSearchTerm = appliedFilter . value . toLowerCase (). split ( " " );
for ( const word of wordsOfSearchTerm ) {
if ( word [ 0 ] == "-" ) {
const wordContent = word . substring ( 1 );
if ( wordsOfObject . includes ( wordContent )) return false ;
2024-07-17 15:48:04 +00:00
} else {
return wordsOfObject . includes ( word );
}
2024-07-17 14:25:11 +00:00
}
return true ;
2024-07-14 20:08:01 +02:00
}
2024-07-15 21:58:32 +02:00
applyFilter ();
2024-07-11 17:07:06 +02:00
const objectModal = createProxyState (
[ chat . objects , selectedObject ],
() => {
if ( selectedObject . value == void 0 ) return /* @__PURE__ */ createElement ( "div" , null );
return ObjectDetailModal (
chat ,
selectedObject . value ,
isShowingObjectModal
);
}
);
2024-07-12 02:30:50 +02:00
const mainView = createProxyState ([ chat . viewType ], () => {
2024-07-11 18:54:56 +02:00
function getViewFunction () {
2024-07-12 02:30:50 +02:00
switch ( chat . viewType . value ) {
2024-07-11 18:54:56 +02:00
case "notes" :
return NoteObjectsView ;
2024-07-12 00:43:58 +02:00
case "kanban" :
return KanbanView ;
2024-07-12 14:30:30 +02:00
case "status" :
return StatusView ;
2024-07-11 18:54:56 +02:00
default :
return AllObjectsView ;
}
}
2024-07-13 17:13:59 +02:00
return getViewFunction ()(
chat ,
2024-07-15 21:58:32 +02:00
showingMessageObjects ,
2024-07-13 17:13:59 +02:00
selectedObject ,
isShowingObjectModal
);
2024-07-11 18:54:56 +02:00
});
2024-07-13 15:10:54 +02:00
return /* @__PURE__ */ createElement ( "div" , { class : "chat-object-view flex-column scroll-no padding-0" }, /* @__PURE__ */ createElement ( "div" , { class : "flex-row align-center border-bottom" }, /* @__PURE__ */ createElement (
2024-07-11 17:07:06 +02:00
"button" ,
{
2024-07-11 18:54:56 +02:00
class : "primary height-100" ,
2024-07-11 17:07:06 +02:00
"on:click" : createObject ,
"aria-label" : translation . createObject
},
/* @__PURE__ */ createElement ( "span" , { class : "icon" }, "add" )
2024-07-11 18:54:56 +02:00
), /* @__PURE__ */ createElement ( "div" , { class : "padding-sm flex flex-row gap justify-center scroll-h width-100" }, ... Object . keys ( viewTypes ). map (
2024-07-12 02:30:50 +02:00
( key ) => ViewTypeToggle ( key , chat . viewType )
2024-07-13 17:13:59 +02:00
)), /* @__PURE__ */ createElement (
"button" ,
{
class : "height-100" ,
"aria-label" : translation . filterObjects ,
"on:click" : showFilters
},
/* @__PURE__ */ createElement ( "span" , { class : "icon" }, "filter_list" )
)), /* @__PURE__ */ createElement (
2024-07-12 14:30:30 +02:00
"div" ,
{
2024-07-13 15:10:54 +02:00
class : "object-content width-100 height-100 flex scroll-no" ,
2024-07-12 14:30:30 +02:00
"children:set" : mainView
}
2024-07-17 14:25:11 +00:00
), /* @__PURE__ */ createElement ( "div" , { class : "modal" , "toggle:open" : isShowingFilterModel }, /* @__PURE__ */ createElement ( "div" , { style : "max-width: 2084px" }, /* @__PURE__ */ createElement ( "main" , { class : "gap" }, /* @__PURE__ */ createElement ( "h2" , null , translation . filterObjects ), /* @__PURE__ */ createElement ( "div" , { class : "flex-column" }, /* @__PURE__ */ createElement ( "label" , { class : "tile" }, /* @__PURE__ */ createElement ( "span" , { class : "icon" }, "search" ), /* @__PURE__ */ createElement ( "div" , null , /* @__PURE__ */ createElement ( "span" , null , translation . searchTitle ), /* @__PURE__ */ createElement (
2024-07-13 17:13:59 +02:00
"input" ,
{
"bind:value" : filterInput ,
"on:enter" : applyFilter ,
2024-07-17 17:22:16 +00:00
placeholder : translation . searchPlaceholder ,
list : "object-searches"
}
), /* @__PURE__ */ createElement (
"datalist" ,
{
hidden : true ,
id : "object-searches" ,
"children:append" : [
previousObjectSearches ,
stringToOptionTag
]
2024-07-13 17:13:59 +02:00
}
2024-07-13 17:18:12 +02:00
)))), /* @__PURE__ */ createElement ( "div" , { class : "flex-row width-input" }, /* @__PURE__ */ createElement (
2024-07-13 17:13:59 +02:00
"button" ,
{
class : "width-50 flex" ,
"on:click" : resetFilter ,
2024-07-17 14:25:11 +00:00
"toggle:disabled" : isFilterEmpty
2024-07-13 17:13:59 +02:00
},
translation . reset
2024-07-15 22:04:29 +02:00
), /* @__PURE__ */ createElement ( "button" , { class : "width-50 flex primary" , "on:click" : applyFilter }, translation . search , /* @__PURE__ */ createElement ( "span" , { class : "icon" }, "arrow_forward" ))), /* @__PURE__ */ createElement ( "hr" , null ), /* @__PURE__ */ createElement ( "b" , { class : "secondary" , "subscribe:innerText" : resultText }), ObjectGridView (
2024-07-15 17:15:52 +02:00
chat ,
2024-07-15 21:58:32 +02:00
showingMessageObjects ,
2024-07-15 17:15:52 +02:00
selectedObject ,
isShowingObjectModal
)), /* @__PURE__ */ createElement ( "button" , { "on:click" : closeFilters }, translation . close , /* @__PURE__ */ createElement ( "span" , { class : "icon" }, "close" )))), /* @__PURE__ */ createElement ( "div" , { "children:set" : objectModal }));
2024-07-11 17:07:06 +02:00
}
2024-07-11 18:54:56 +02:00
function ViewTypeToggle ( key , selection ) {
const [ label , icon ] = viewTypes [ key ];
function select () {
selection . value = key ;
}
const isSelected = createProxyState (
[ selection ],
() => selection . value == key
);
return /* @__PURE__ */ createElement ( "button" , { "aria-label" : label , "on:click" : select , "toggle:selected" : isSelected }, /* @__PURE__ */ createElement ( "span" , { class : "icon" }, icon ));
}
2024-07-11 17:07:06 +02:00
2024-07-11 01:47:43 +02:00
// src/Views/Chat/threadView.tsx
2024-07-09 17:23:29 +02:00
function ThreadView ( chat ) {
const messageConverter = ( message ) => {
2024-07-10 15:08:06 +02:00
function resendMessage () {
chat . resendMessage ( message );
}
2024-07-09 17:23:29 +02:00
function copyMessage () {
navigator . clipboard . writeText ( message . body );
}
function decrypt2 () {
chat . decryptReceivedMessage ( message );
}
function remove () {
chat . deleteMessage ( message );
}
2024-07-09 17:38:50 +02:00
const messageBody = createProxyState (
[ chat . messages ],
() => message . body
);
2024-07-10 15:08:06 +02:00
return /* @__PURE__ */ createElement ( "div" , { class : "tile width-100 flex-no padding-0" }, /* @__PURE__ */ createElement ( "div" , { class : "flex-column" }, /* @__PURE__ */ createElement ( "div" , { class : "flex-row justify-apart align-center secondary" }, /* @__PURE__ */ createElement ( "span" , { class : "padding-h ellipsis" }, /* @__PURE__ */ createElement ( "b" , { class : "info" }, message . sender )), /* @__PURE__ */ createElement ( "span" , { class : "flex-row" }, /* @__PURE__ */ createElement (
"button" ,
{
"aria-label" : translation . resendMessage ,
"on:click" : resendMessage ,
"toggle:disabled" : chat . cannotResendMessage
},
/* @__PURE__ */ createElement ( "span" , { class : "icon" }, "replay" )
), /* @__PURE__ */ createElement (
2024-07-09 17:23:29 +02:00
"button" ,
{
"aria-label" : translation . copyMessage ,
"on:click" : copyMessage
},
/* @__PURE__ */ createElement ( "span" , { class : "icon" }, "content_copy" )
), /* @__PURE__ */ createElement (
"button" ,
{
"aria-label" : translation . decryptMessage ,
"on:click" : decrypt2
},
/* @__PURE__ */ createElement ( "span" , { class : "icon" }, "key" )
2024-07-10 15:20:09 +02:00
), /* @__PURE__ */ createElement ( "button" , { "aria-label" : translation . deleteMessage , "on:click" : remove }, /* @__PURE__ */ createElement ( "span" , { class : "icon" }, "delete" )))), /* @__PURE__ */ createElement ( "div" , { class : "flex-column padding-h padding-bottom" }, /* @__PURE__ */ createElement ( "b" , { class : "break-word" , "subscribe:innerText" : messageBody }), /* @__PURE__ */ createElement ( "span" , { class : "secondary" }, /* @__PURE__ */ createElement ( "b" , null , new Date ( message . isoDate ). toLocaleString ()), /* @__PURE__ */ createElement ( "br" , null ), message . channel ))));
2024-07-09 17:23:29 +02:00
};
2024-07-10 16:37:42 +02:00
const outboxMessageConverter = ( message ) => {
function remove () {
chat . deleteOutboxMessage ( message );
}
return /* @__PURE__ */ createElement ( "div" , { class : "tile width-100 flex-no padding-0" }, /* @__PURE__ */ createElement ( "div" , { class : "flex-column" }, /* @__PURE__ */ createElement ( "div" , { class : "flex-row justify-apart align-center" }, /* @__PURE__ */ createElement ( "b" , { class : "error padding-h" }, translation . messageInOutbox ), /* @__PURE__ */ createElement ( "span" , { class : "flex-row secondary" }, /* @__PURE__ */ createElement ( "button" , { "aria-label" : translation . deleteMessage , "on:click" : remove }, /* @__PURE__ */ createElement ( "span" , { class : "icon" }, "delete" )))), /* @__PURE__ */ createElement ( "div" , { class : "flex-column padding-h padding-bottom" }, /* @__PURE__ */ createElement ( "b" , { class : "break-word" }, message . body ), /* @__PURE__ */ createElement ( "span" , { class : "secondary" }, /* @__PURE__ */ createElement ( "b" , null , new Date ( message . isoDate ). toLocaleString ()), /* @__PURE__ */ createElement ( "br" , null ), message . channel ))));
};
const messageList = /* @__PURE__ */ createElement (
2024-07-09 17:23:29 +02:00
"div" ,
{
class : "flex-column gap" ,
"children:append" : [ chat . messages , messageConverter ]
}
);
2024-07-10 16:37:42 +02:00
const outboxList = /* @__PURE__ */ createElement (
"div" ,
{
class : "flex-column gap" ,
"children:append" : [ chat . outbox , outboxMessageConverter ]
}
);
2024-07-13 15:10:54 +02:00
const listWrapper = /* @__PURE__ */ createElement ( "div" , { class : "thread-view flex-column gap" }, messageList , outboxList );
2024-07-10 16:37:42 +02:00
function scrollToBottom () {
2024-07-11 01:03:07 +02:00
listWrapper . scrollTop = listWrapper . scrollHeight ;
}
function scrollToBottomIfAppropriate () {
2024-07-10 16:37:42 +02:00
const scrollFromBottom = listWrapper . scrollHeight - ( listWrapper . scrollTop + listWrapper . offsetHeight );
2024-07-09 18:35:48 +02:00
if ( scrollFromBottom > 400 ) return ;
2024-07-11 01:03:07 +02:00
scrollToBottom ();
2024-07-10 16:37:42 +02:00
}
2024-07-11 01:03:07 +02:00
chat . messages . handleAddition ( scrollToBottomIfAppropriate );
chat . outbox . handleAddition ( scrollToBottomIfAppropriate );
2024-07-11 21:34:21 +02:00
isShowingObjects . subscribe (() => scrollToBottom ());
2024-07-11 01:03:07 +02:00
setTimeout (() => scrollToBottom (), 50 );
2024-07-10 16:37:42 +02:00
return listWrapper ;
2024-07-09 17:23:29 +02:00
}
// src/Tabs/messageTab.tsx
function MessageTab () {
const messageTabContent = createProxyState ([ selectedChat ], () => {
if ( selectedChat . value == void 0 )
return /* @__PURE__ */ createElement ( "div" , { class : "width-100 height-100 flex-column align-center justify-center" }, /* @__PURE__ */ createElement ( "span" , { class : "secondary" }, translation . noChatSelected ));
const chat = selectedChat . value ;
const isShowingOptions = new State ( false );
function showOptions () {
isShowingOptions . value = true ;
}
2024-07-09 18:21:28 +02:00
return [
/* @__PURE__ */ createElement ( "header" , { class : "padding-0" }, /* @__PURE__ */ createElement ( "span" , { class : "flex-row align-center" }, /* @__PURE__ */ createElement ( "button" , { "aria-label" : translation . back , "on:click" : closeChatView }, /* @__PURE__ */ createElement ( "span" , { class : "icon" }, "arrow_back" )), /* @__PURE__ */ createElement ( "span" , { "subscribe:innerText" : chat . primaryChannel })), /* @__PURE__ */ createElement ( "span" , null , /* @__PURE__ */ createElement (
2024-07-10 19:07:58 +02:00
"button" ,
{
2024-07-11 17:07:06 +02:00
"aria-label" : translation . showObjects ,
2024-07-13 15:10:54 +02:00
"on:click" : toggleObjects ,
2024-07-11 21:34:21 +02:00
"toggle:selected" : isShowingObjects
2024-07-10 19:07:58 +02:00
},
2024-07-11 02:30:38 +02:00
/* @__PURE__ */ createElement ( "span" , { class : "icon" }, "deployed_code" )
2024-07-13 15:10:54 +02:00
), /* @__PURE__ */ createElement (
"button" ,
{
"aria-label" : translation . showObjects ,
"on:click" : toggleChat ,
"toggle:selected" : isChatVisible
},
/* @__PURE__ */ createElement ( "span" , { class : "icon" }, "forum" )
2024-07-10 19:07:58 +02:00
), /* @__PURE__ */ createElement (
2024-07-09 18:21:28 +02:00
"button" ,
{
"aria-label" : translation . showChatOptions ,
"on:click" : showOptions
},
/* @__PURE__ */ createElement ( "span" , { class : "icon" }, "tune" )
))),
2024-07-12 00:43:58 +02:00
ObjectPane ( chat ),
2024-07-09 18:21:28 +02:00
ThreadView ( chat ),
/* @__PURE__ */ createElement ( "footer" , null , MessageComposer ( chat )),
ChatOptionModal ( chat , isShowingOptions )
];
2024-07-09 17:23:29 +02:00
});
2024-07-10 19:07:58 +02:00
return /* @__PURE__ */ createElement (
"article" ,
{
id : "message-tab" ,
2024-07-13 15:10:54 +02:00
"children:set" : messageTabContent ,
"toggle:showingobjects" : isShowingObjects ,
"toggle:chatvisible" : isChatVisible ,
"toggle:chatopen" : isChatOpen
2024-07-10 19:07:58 +02:00
}
);
2024-07-09 17:23:29 +02:00
}
2024-07-11 01:47:43 +02:00
// src/Views/Overview/chatListSection.tsx
2024-07-09 17:23:29 +02:00
var chatConverter = ( chat ) => {
function select () {
selectChat ( chat );
}
const isSelected = createProxyState (
[ selectedChat ],
() => selectedChat . value == chat
);
2024-07-10 15:40:25 +02:00
return /* @__PURE__ */ createElement (
"button" ,
{
class : "tile" ,
"on:click" : select ,
"toggle:selected" : isSelected ,
"toggle:unread" : chat . hasUnreadMessages
},
/* @__PURE__ */ createElement ( "div" , null , /* @__PURE__ */ createElement ( "b" , { class : "ellipsis" , "subscribe:innerText" : chat . primaryChannel })),
/* @__PURE__ */ createElement ( "span" , { class : "icon" }, "arrow_forward" )
);
2024-07-09 17:23:29 +02:00
};
function ChatListSection () {
2024-07-09 19:17:11 +02:00
return /* @__PURE__ */ createElement ( "div" , { class : "flex-column" }, /* @__PURE__ */ createElement ( "h2" , null , translation . chats ), /* @__PURE__ */ createElement ( "label" , { class : "tile" }, /* @__PURE__ */ createElement ( "span" , { class : "icon" }, "forum" ), /* @__PURE__ */ createElement ( "div" , null , /* @__PURE__ */ createElement ( "span" , null , translation . primaryChannel ), /* @__PURE__ */ createElement (
2024-07-09 17:23:29 +02:00
"input" ,
{
"bind:value" : newChatName ,
2024-07-09 19:17:11 +02:00
placeholder : translation . primaryChannelPlaceholder ,
2024-07-09 17:23:29 +02:00
"on:enter" : createChat
}
))), /* @__PURE__ */ createElement ( "div" , { class : "flex-row justify-end" }, /* @__PURE__ */ createElement (
"button" ,
{
class : "primary width-50" ,
"toggle:disabled" : cannotCreateChat ,
"on:click" : createChat
},
translation . addChat ,
/* @__PURE__ */ createElement ( "span" , { class : "icon" }, "add" )
)), /* @__PURE__ */ createElement ( "hr" , null ), /* @__PURE__ */ createElement (
"div" ,
{
class : "flex-column gap" ,
"children:append" : [ chats , chatConverter ]
}
));
}
2024-07-11 01:47:43 +02:00
// src/Views/Overview/connectionSection.tsx
2024-07-09 17:23:29 +02:00
function ConnectionSection () {
2024-07-12 20:22:18 +02:00
const stringToPreviouAddressOption = ( value ) => {
const isSelected = value == serverAddressInput . value ;
return /* @__PURE__ */ createElement ( "option" , { "toggle:selected" : isSelected }, value );
};
2024-07-09 17:23:29 +02:00
return /* @__PURE__ */ createElement ( "div" , { class : "flex-column" }, /* @__PURE__ */ createElement ( "h2" , null , translation . connection ), /* @__PURE__ */ createElement ( "label" , { class : "tile" }, /* @__PURE__ */ createElement ( "span" , { class : "icon" }, "cell_tower" ), /* @__PURE__ */ createElement ( "div" , null , /* @__PURE__ */ createElement ( "span" , null , translation . serverAddress ), /* @__PURE__ */ createElement (
"input" ,
{
"bind:value" : serverAddressInput ,
"on:enter" : connect ,
2024-07-09 20:09:09 +02:00
placeholder : translation . serverAddressPlaceholder ,
list : "previous-addresses"
}
), /* @__PURE__ */ createElement (
"datalist" ,
{
hidden : true ,
id : "previous-addresses" ,
2024-07-12 02:24:48 +02:00
"children:append" : [ previousAddresses , stringToOptionTag ]
2024-07-09 17:23:29 +02:00
}
2024-07-12 19:58:29 +02:00
))), /* @__PURE__ */ createElement ( "label" , { class : "tile" }, /* @__PURE__ */ createElement ( "span" , { class : "icon" }, "history" ), /* @__PURE__ */ createElement ( "div" , null , /* @__PURE__ */ createElement ( "span" , null , translation . previousConnections ), /* @__PURE__ */ createElement (
"select" ,
{
"bind:value" : serverAddressInput ,
2024-07-12 20:22:18 +02:00
"children:append" : [ previousAddresses , stringToPreviouAddressOption ]
2024-07-12 19:58:29 +02:00
}
), /* @__PURE__ */ createElement ( "span" , { class : "icon" }, "arrow_drop_down" ))), /* @__PURE__ */ createElement ( "div" , { class : "flex-row width-input justify-end" }, /* @__PURE__ */ createElement (
2024-07-09 17:23:29 +02:00
"button" ,
{
class : "danger width-100 flex-1 justify-center" ,
"aria-label" : translation . disconnect ,
"on:click" : disconnect ,
"toggle:disabled" : cannotDisonnect
},
/* @__PURE__ */ createElement ( "span" , { class : "icon" }, "close" )
), /* @__PURE__ */ createElement (
"button" ,
{
class : "width-100 flex-1 justify-center" ,
"aria-label" : translation . undoChanges ,
"on:click" : resetAddressInput ,
"toggle:disabled" : cannotResetAddress
},
/* @__PURE__ */ createElement ( "span" , { class : "icon" }, "undo" )
), /* @__PURE__ */ createElement (
"button" ,
{
class : "primary width-100 flex-1 justify-center" ,
"aria-label" : translation . connectToServer ,
"on:click" : connect ,
"toggle:disabled" : cannotConnect
},
/* @__PURE__ */ createElement ( "span" , { class : "icon" }, "arrow_forward" )
)), /* @__PURE__ */ createElement ( "hr" , null ), /* @__PURE__ */ createElement ( "div" , { class : "tile" }, /* @__PURE__ */ createElement ( "span" , { class : "icon" }, "inbox" ), /* @__PURE__ */ createElement ( "div" , null , /* @__PURE__ */ createElement ( "b" , null , translation . mailbox ), /* @__PURE__ */ createElement ( "span" , { class : "secondary" }, translation . mailboxExplanation ))), /* @__PURE__ */ createElement ( "div" , { class : "flex-row width-input justify-end" }, /* @__PURE__ */ createElement (
"button" ,
{
class : "danger width-100 flex-1" ,
"on:click" : deleteMailbox ,
"toggle:disabled" : cannotDeleteMailbox
},
translation . deleteMailbox
), /* @__PURE__ */ createElement (
"button" ,
{
class : "primary width-100 flex-1" ,
"on:click" : requestMailbox ,
"toggle:disabled" : cannotRequestMailbox
},
translation . requestMailbox ,
/* @__PURE__ */ createElement ( "span" , { class : "icon" }, "arrow_forward" )
2024-07-12 19:58:29 +02:00
)), /* @__PURE__ */ createElement ( "hr" , null ), /* @__PURE__ */ createElement ( "div" , { class : "tile" }, /* @__PURE__ */ createElement ( "span" , { class : "icon" }, "outbox" ), /* @__PURE__ */ createElement ( "div" , null , /* @__PURE__ */ createElement ( "b" , null , translation . outbox ), /* @__PURE__ */ createElement (
"span" ,
{
"set:class" : outboxTextStyle ,
"subscribe:innerText" : outboxText
}
))));
2024-07-09 17:23:29 +02:00
}
2024-07-11 01:47:43 +02:00
// src/Views/Overview/personalSection.tsx
2024-07-09 17:27:15 +02:00
function PersonalSection () {
2024-07-09 19:17:11 +02:00
return /* @__PURE__ */ createElement ( "div" , { class : "flex-column" }, /* @__PURE__ */ createElement ( "label" , { class : "tile" }, /* @__PURE__ */ createElement ( "span" , { class : "icon" }, "account_circle" ), /* @__PURE__ */ createElement ( "div" , null , /* @__PURE__ */ createElement ( "span" , null , translation . yourName ), /* @__PURE__ */ createElement (
2024-07-09 17:27:15 +02:00
"input" ,
{
"bind:value" : senderName ,
placeholder : translation . namePlaceholder
}
))));
}
2024-07-09 17:23:29 +02:00
// src/Tabs/overviewTab.tsx
function OverviewTab () {
2024-07-12 21:11:33 +02:00
return /* @__PURE__ */ createElement ( "article" , { id : "settings-tab" , "toggle:connected" : isConnected }, /* @__PURE__ */ createElement ( "header" , null , translation . overview , /* @__PURE__ */ createElement ( "button" , { "aria-label" : translation . showSettings , "on:click" : toggleSettings }, /* @__PURE__ */ createElement ( "span" , { class : "icon" }, "settings" ))), /* @__PURE__ */ createElement ( "div" , { class : "flex-column large-gap" }, /* @__PURE__ */ createElement ( "div" , { class : "tile error flex-no" , "toggle:hidden" : isEncryptionAvailable }, /* @__PURE__ */ createElement ( "span" , { class : "icon" }, "warning" ), /* @__PURE__ */ createElement ( "div" , null , /* @__PURE__ */ createElement ( "b" , null , translation . encryptionUnavailableTitle ), /* @__PURE__ */ createElement ( "span" , { class : "secondary" }, translation . encryptionUnavailableMessage ))), PersonalSection (), ConnectionSection (), ChatListSection ()));
}
// src/Views/settingsModal.tsx
function SettingsModal () {
2024-07-17 17:22:16 +00:00
return /* @__PURE__ */ createElement ( "div" , { class : "modal" , "toggle:open" : isPresentingSettingsModal }, /* @__PURE__ */ createElement ( "div" , null , /* @__PURE__ */ createElement ( "main" , null , /* @__PURE__ */ createElement ( "h2" , null , translation . settings ), /* @__PURE__ */ createElement ( "div" , { class : "flex-row width-input gap" }, /* @__PURE__ */ createElement ( "button" , { class : "width-100 flex justify-start" , "on:click" : zoomOut }, /* @__PURE__ */ createElement ( "span" , { class : "icon" }, "zoom_out" ), translation . zoomOut ), /* @__PURE__ */ createElement ( "button" , { class : "width-100 flex justify-start" , "on:click" : zoomIn }, /* @__PURE__ */ createElement ( "span" , { class : "icon" }, "zoom_in" ), translation . zoomIn )), /* @__PURE__ */ createElement ( "hr" , null ), /* @__PURE__ */ createElement ( "div" , { class : "flex-column width-input" }, /* @__PURE__ */ createElement ( "button" , { class : "tile width-100 flex-1" , "on:click" : repairApp }, /* @__PURE__ */ createElement ( "span" , { class : "icon" }, "handyman" ), translation . repairApp )), /* @__PURE__ */ createElement ( "hr" , null ), /* @__PURE__ */ createElement ( "div" , { class : "flex-column width-input gap" }, /* @__PURE__ */ createElement ( "button" , { class : "tile width-100 flex-1" , "on:click" : clearAddresses }, /* @__PURE__ */ createElement ( "span" , { class : "icon" }, "cell_tower" ), translation . clearAddresses ), /* @__PURE__ */ createElement ( "button" , { class : "tile width-100 flex-1" , "on:click" : clearCategories }, /* @__PURE__ */ createElement ( "span" , { class : "icon" }, icons . categoryName ), translation . clearCategories ), /* @__PURE__ */ createElement ( "button" , { class : "tile width-100 flex-1" , "on:click" : clearStatuses }, /* @__PURE__ */ createElement ( "span" , { class : "icon" }, icons . status ), translation . clearStatuses ), /* @__PURE__ */ createElement (
"button" ,
{
class : "tile width-100 flex-1" ,
"on:click" : clearObjectSearches
},
/* @__PURE__ */ createElement ( "span" , { class : "icon" }, "search" ),
translation . clearObjectFilters
))), /* @__PURE__ */ createElement ( "button" , { class : "width-100" , "on:click" : toggleSettings }, translation . close , /* @__PURE__ */ createElement ( "span" , { class : "icon" }, "close" ))));
2024-07-09 17:23:29 +02:00
}
// src/index.tsx
2024-07-12 21:11:33 +02:00
document . querySelector ( "main" ). append ( OverviewTab (), MessageTab (), SettingsModal ());
2024-07-07 22:11:18 +02:00
document . querySelector ( "main" ). classList . add ( "split" );
2024-07-07 13:43:18 +02:00
})();