mirror of
https://github.com/chatmail/core.git
synced 2026-05-08 09:26:29 +03:00
update todo document
remove specific api stuff for now, we now have the an incremental aproach on moving not the all at-once effort I though it would be
This commit is contained in:
@@ -1,35 +1,18 @@
|
|||||||
## Core system
|
# TODO
|
||||||
|
|
||||||
- [X] Base structure of JSON API code
|
- [ ] different test type to simulate two devices: to test autocrypt_initiate_key_transfer & autocrypt_continue_key_transfer
|
||||||
- [X] Implement the first methods for testing + the code that should later be generated by the proc macro
|
|
||||||
- [X] Create the proc macro
|
|
||||||
- [X] json api
|
|
||||||
- [X] ts types
|
|
||||||
- [X] arguments (no args, one argument, multiple args)
|
|
||||||
- [X] return type
|
|
||||||
- [X] custom types as type aliases that ts file looks prettier
|
|
||||||
|
|
||||||
|
## MVP - Websocket server&client
|
||||||
|
|
||||||
## Pre - MVP
|
For kaiOS and other experiments, like a deltachat "web" over network from an android phone.
|
||||||
|
|
||||||
- [X] Web socket server
|
|
||||||
- [WIP] Web socket client (ts)
|
|
||||||
- [X] backend connection state changed events
|
|
||||||
- [X] Reconnect on connection loss / connection state
|
|
||||||
- [ ] find a way to type the event emitter callback functions
|
|
||||||
- [X] Events
|
|
||||||
|
|
||||||
## MVP
|
|
||||||
|
|
||||||
- [X] mocha integration test for ts api
|
|
||||||
- [X] basic tests
|
|
||||||
- [X] advanced / "online tests" (mailadm for burner accounts)
|
|
||||||
- [ ] coverage for a majority of the API
|
- [ ] coverage for a majority of the API
|
||||||
- [ ] Blobs served
|
- [ ] Blobs served
|
||||||
- [ ] Blob upload (for attachments, setting profile-picture, importing backup and so on)
|
- [ ] Blob upload (for attachments, setting profile-picture, importing backup and so on)
|
||||||
|
- [ ] other way blobs can be addressed when using websocket vs. jsonrpc over dc-node
|
||||||
- [ ] Web push API? At least some kind of notification hook closure this lib can accept.
|
- [ ] Web push API? At least some kind of notification hook closure this lib can accept.
|
||||||
|
|
||||||
## Other Ideas
|
### Other Ideas for the Websocket server
|
||||||
|
|
||||||
- [ ] make sure there can only be one connection at a time to the ws
|
- [ ] make sure there can only be one connection at a time to the ws
|
||||||
- why? , it could give problems if its commanded from multiple connections
|
- why? , it could give problems if its commanded from multiple connections
|
||||||
@@ -37,311 +20,9 @@
|
|||||||
- [ ] authenticated connection?
|
- [ ] authenticated connection?
|
||||||
- [ ] Look into unit-testing for the proc macros?
|
- [ ] Look into unit-testing for the proc macros?
|
||||||
- [ ] proc macro taking over doc comments to generated typescript file
|
- [ ] proc macro taking over doc comments to generated typescript file
|
||||||
- [X] GH action for tests (rust and typescript)
|
|
||||||
- [X] rust test
|
|
||||||
- [X] rust fmt
|
|
||||||
- [X] rust clippy
|
|
||||||
- [X] tsc check
|
|
||||||
- [X] prettier
|
|
||||||
- [X] mocha
|
|
||||||
- [X] scripts to check&fix prettier formatting
|
|
||||||
|
|
||||||
|
## Desktop Apis
|
||||||
|
|
||||||
|
Incomplete todo for desktop api porting, just some remainders for points that might need more work:
|
||||||
|
|
||||||
## Apis
|
- [ ] manual start/stop io functions in the api for context and accounts, so "not syncing all accounts" can still be done in desktop -> webserver should then not do start io on all accounts by default
|
||||||
|
|
||||||
replicate desktop api feature set:
|
|
||||||
|
|
||||||
(this feature set is based on desktop version `1.20`, needs to be updated in the future)
|
|
||||||
|
|
||||||
```rs
|
|
||||||
|
|
||||||
|
|
||||||
struct sendMessageParams {
|
|
||||||
text: Option<String>,
|
|
||||||
filename: Option<String>, // TODO we need to think about blobs some more
|
|
||||||
location: Option<(u32,u32)>,
|
|
||||||
quote_message_id: Option<u32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct QrCodeResponse = {
|
|
||||||
state: u32 // also enum in reality, for simlicity u32 here
|
|
||||||
id: u32
|
|
||||||
text1: String
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Api {
|
|
||||||
|
|
||||||
// root ---------------------------------------------------------------
|
|
||||||
|
|
||||||
// NEEDS_THE_BLOB_QUESTION_ANSWERED_EVENTUALLY
|
|
||||||
async fn sc_set_profile_picture(&self, new_image: String) -> Result<()> {}
|
|
||||||
|
|
||||||
// NEEDS_THE_BLOB_QUESTION_ANSWERED_EVENTUALLY
|
|
||||||
// 'getProfilePicture' equals to `dc.getContact(C.DC_CONTACT_ID_SELF).getProfileImage()` or `dc.get_config("selfavatar")`
|
|
||||||
|
|
||||||
async fn sc_join_secure_join(&self, qrCode: String) -> Result<u32> {}
|
|
||||||
async fn sc_stop_ongoing_process(&self) -> Result<u32> {}
|
|
||||||
async fn sc_check_qr_code(&self, qrCode: String) -> Result<QrCodeResponse> {}
|
|
||||||
|
|
||||||
// login ----------------------------------------------------
|
|
||||||
|
|
||||||
// INFO: login functions need to call stop&start io where applicable
|
|
||||||
|
|
||||||
// login.newLogin:
|
|
||||||
// do instead in frontend:
|
|
||||||
// 1. call `add_account`
|
|
||||||
// 2. call `select_account`
|
|
||||||
// 3. set credentials via set config
|
|
||||||
// 4. call `sc_configure`
|
|
||||||
|
|
||||||
// login.getLogins - is already implemented: `get_all_accounts`
|
|
||||||
|
|
||||||
// login.loadAccount - Basically `select_account`
|
|
||||||
|
|
||||||
// login.logout -> TODO: unselect account, which isn't implemented in the core yet
|
|
||||||
|
|
||||||
// login.forgetAccount -> `remove_account`
|
|
||||||
|
|
||||||
// login.getLastLoggedInAccount -> `get_selected_account_id`
|
|
||||||
|
|
||||||
// login.updateCredentials -> do instead: set config then call `sc_configure`
|
|
||||||
|
|
||||||
// backup -------------------------------------------------------------
|
|
||||||
|
|
||||||
// INFO: backup functions need to call stop&start io
|
|
||||||
|
|
||||||
// NEEDS_THE_BLOB_QUESTION_ANSWERED_EVENTUALLY
|
|
||||||
async fn sc_backup_export(&self, out_dir: String) -> Result<()> {}
|
|
||||||
// NEEDS_THE_BLOB_QUESTION_ANSWERED_EVENTUALLY
|
|
||||||
async fn sc_backup_import(&self, file: String) -> Result<()> {} // will not return the same as in desktop because this function imports backup to the current context unlike it was in desktop
|
|
||||||
|
|
||||||
// chatList -----------------------------------------------------------
|
|
||||||
|
|
||||||
// chatList.selectChat - will be removed from desktop
|
|
||||||
// chatList.getSelectedChatId - will be removed from desktop
|
|
||||||
// chatList.onChatModified - will be removed from desktop
|
|
||||||
|
|
||||||
async fn sc_chatlist_get_general_fresh_message_counter(&self) -> Result<u32> // this method might be used for a favicon badge counter
|
|
||||||
|
|
||||||
// contacts ------------------------------------------------------------
|
|
||||||
|
|
||||||
async fn sc_contacts_change_nickname(&self, contact_id: u32, new_name: String) -> Result<()>
|
|
||||||
|
|
||||||
|
|
||||||
// contacts.getChatIdByContactId - very similar to sc_contacts_create_chat_by_contact_id
|
|
||||||
// contacts.getDMChatId - very similar to sc_contacts_create_chat_by_contact_id
|
|
||||||
|
|
||||||
async fn sc_contacts_get_encryption_info(&self, contact_id: u32) -> Result<String>
|
|
||||||
|
|
||||||
async fn sc_contacts_lookup_contact_id_by_addr(&self, email: String) -> Result<u32>
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
```
|
|
||||||
```ts
|
|
||||||
|
|
||||||
class DeltaRemote {
|
|
||||||
// chat ---------------------------------------------------------------
|
|
||||||
call(
|
|
||||||
fnName: 'chat.getChatMedia',
|
|
||||||
chatId: number,
|
|
||||||
msgType1: number,
|
|
||||||
msgType2: number
|
|
||||||
): Promise<MessageType[]>
|
|
||||||
call(fnName: 'chat.getEncryptionInfo', chatId: number): Promise<string>
|
|
||||||
call(fnName: 'chat.getQrCode', chatId?: number): Promise<string>
|
|
||||||
call(fnName: 'chat.leaveGroup', chatId: number): Promise<void>
|
|
||||||
call(fnName: 'chat.setName', chatId: number, name: string): Promise<boolean>
|
|
||||||
call(
|
|
||||||
fnName: 'chat.modifyGroup',
|
|
||||||
chatId: number,
|
|
||||||
name: string,
|
|
||||||
image: string,
|
|
||||||
remove: number[],
|
|
||||||
add: number[]
|
|
||||||
): Promise<boolean>
|
|
||||||
call(
|
|
||||||
fnName: 'chat.addContactToChat',
|
|
||||||
chatId: number,
|
|
||||||
contactId: number
|
|
||||||
): Promise<boolean>
|
|
||||||
call(
|
|
||||||
fnName: 'chat.setProfileImage',
|
|
||||||
chatId: number,
|
|
||||||
newImage: string
|
|
||||||
): Promise<boolean>
|
|
||||||
call(
|
|
||||||
fnName: 'chat.setMuteDuration',
|
|
||||||
chatId: number,
|
|
||||||
duration: MuteDuration
|
|
||||||
): Promise<boolean>
|
|
||||||
call(
|
|
||||||
fnName: 'chat.createGroupChat',
|
|
||||||
verified: boolean,
|
|
||||||
name: string
|
|
||||||
): Promise<number>
|
|
||||||
call(fnName: 'chat.delete', chatId: number): Promise<void>
|
|
||||||
call(
|
|
||||||
fnName: 'chat.setVisibility',
|
|
||||||
chatId: number,
|
|
||||||
visibility:
|
|
||||||
| C.DC_CERTCK_AUTO
|
|
||||||
| C.DC_CERTCK_STRICT
|
|
||||||
| C.DC_CHAT_VISIBILITY_PINNED
|
|
||||||
): Promise<void>
|
|
||||||
call(fnName: 'chat.getChatContacts', chatId: number): Promise<number[]>
|
|
||||||
call(fnName: 'chat.markNoticedChat', chatId: number): Promise<void>
|
|
||||||
call(fnName: 'chat.getChatEphemeralTimer', chatId: number): Promise<number>
|
|
||||||
call(
|
|
||||||
fnName: 'chat.setChatEphemeralTimer',
|
|
||||||
chatId: number,
|
|
||||||
ephemeralTimer: number
|
|
||||||
): Promise<void>
|
|
||||||
call(fnName: 'chat.sendVideoChatInvitation', chatId: number): Promise<number>
|
|
||||||
call(
|
|
||||||
fnName: 'chat.decideOnContactRequest',
|
|
||||||
messageId: number,
|
|
||||||
decision:
|
|
||||||
| C.DC_DECISION_START_CHAT
|
|
||||||
| C.DC_DECISION_NOT_NOW
|
|
||||||
| C.DC_DECISION_BLOCK
|
|
||||||
): Promise<number>
|
|
||||||
// locations ----------------------------------------------------------
|
|
||||||
call(
|
|
||||||
fnName: 'locations.setLocation',
|
|
||||||
latitude: number,
|
|
||||||
longitude: number,
|
|
||||||
accuracy: number
|
|
||||||
): Promise<void>
|
|
||||||
call(
|
|
||||||
fnName: 'locations.getLocations',
|
|
||||||
chatId: number,
|
|
||||||
contactId: number,
|
|
||||||
timestampFrom: number,
|
|
||||||
timestampTo: number
|
|
||||||
): Promise<JsonLocations>
|
|
||||||
|
|
||||||
// NOTHING HERE that is called directly from the frontend, yet
|
|
||||||
// messageList --------------------------------------------------------
|
|
||||||
call(
|
|
||||||
fnName: 'messageList.sendMessage',
|
|
||||||
chatId: number,
|
|
||||||
params: sendMessageParams
|
|
||||||
): Promise<[number, MessageType | null]>
|
|
||||||
call(
|
|
||||||
fnName: 'messageList.sendSticker',
|
|
||||||
chatId: number,
|
|
||||||
stickerPath: string
|
|
||||||
): Promise<void>
|
|
||||||
call(fnName: 'messageList.deleteMessage', id: number): Promise<void>
|
|
||||||
call(fnName: 'messageList.getMessageInfo', msgId: number): Promise<string>
|
|
||||||
call(
|
|
||||||
fnName: 'messageList.getDraft',
|
|
||||||
chatId: number
|
|
||||||
): Promise<MessageType | null>
|
|
||||||
call(
|
|
||||||
fnName: 'messageList.setDraft',
|
|
||||||
chatId: number,
|
|
||||||
{
|
|
||||||
text,
|
|
||||||
file,
|
|
||||||
quotedMessageId,
|
|
||||||
}: { text?: string; file?: string; quotedMessageId?: number }
|
|
||||||
): Promise<void>
|
|
||||||
call(
|
|
||||||
fnName: 'messageList.messageIdToJson',
|
|
||||||
id: number
|
|
||||||
): Promise<{ msg: null } | MessageType>
|
|
||||||
call(
|
|
||||||
fnName: 'messageList.forwardMessage',
|
|
||||||
msgId: number,
|
|
||||||
chatId: number
|
|
||||||
): Promise<void>
|
|
||||||
call(
|
|
||||||
fnName: 'messageList.searchMessages',
|
|
||||||
query: string,
|
|
||||||
chatId?: number
|
|
||||||
): Promise<number[]>
|
|
||||||
call(
|
|
||||||
fnName: 'messageList.msgIds2SearchResultItems',
|
|
||||||
msgIds: number[]
|
|
||||||
): Promise<{ [id: number]: MessageSearchResult }>
|
|
||||||
call(
|
|
||||||
fnName: 'messageList.saveMessageHTML2Disk',
|
|
||||||
messageId: number
|
|
||||||
): Promise<string>
|
|
||||||
// settings -----------------------------------------------------------
|
|
||||||
call(fnName: 'settings.keysImport', directory: string): Promise<void>
|
|
||||||
call(fnName: 'settings.keysExport', directory: string): Promise<void>
|
|
||||||
call(
|
|
||||||
fnName: 'settings.serverFlags',
|
|
||||||
{
|
|
||||||
mail_security,
|
|
||||||
send_security,
|
|
||||||
}: {
|
|
||||||
mail_security?: string
|
|
||||||
send_security?: string
|
|
||||||
}
|
|
||||||
): Promise<number | ''>
|
|
||||||
call(
|
|
||||||
fnName: 'settings.setDesktopSetting',
|
|
||||||
key: keyof DesktopSettings,
|
|
||||||
value: string | number | boolean
|
|
||||||
): Promise<boolean>
|
|
||||||
call(fnName: 'settings.getDesktopSettings'): Promise<DesktopSettings>
|
|
||||||
call(
|
|
||||||
fnName: 'settings.saveBackgroundImage',
|
|
||||||
file: string,
|
|
||||||
isDefaultPicture: boolean
|
|
||||||
): Promise<string>
|
|
||||||
call(
|
|
||||||
fnName: 'settings.estimateAutodeleteCount',
|
|
||||||
fromServer: boolean,
|
|
||||||
seconds: number
|
|
||||||
): Promise<number>
|
|
||||||
// stickers -----------------------------------------------------------
|
|
||||||
call(
|
|
||||||
fnName: 'stickers.getStickers'
|
|
||||||
): Promise<{
|
|
||||||
[key: string]: string[]
|
|
||||||
}> // todo move to extras? because its not directly elated to core
|
|
||||||
// context ------------------------------------------------------------
|
|
||||||
call(fnName: 'context.maybeNetwork'): Promise<void>
|
|
||||||
// burner accounts ------------------------------------------------------------
|
|
||||||
call(
|
|
||||||
fnName: 'burnerAccounts.create',
|
|
||||||
url: string
|
|
||||||
): Promise<{ email: string; password: string }> // think about how to improve that api - probably use core api instead
|
|
||||||
// extras -------------------------------------------------------------
|
|
||||||
call(fnName: 'extras.getLocaleData', locale: string): Promise<LocaleData>
|
|
||||||
call(fnName: 'extras.setLocale', locale: string): Promise<void>
|
|
||||||
call(
|
|
||||||
fnName: 'extras.getActiveTheme'
|
|
||||||
): Promise<{
|
|
||||||
theme: Theme
|
|
||||||
data: string
|
|
||||||
} | null>
|
|
||||||
call(fnName: 'extras.setThemeFilePath', address: string): void
|
|
||||||
call(fnName: 'extras.getAvailableThemes'): Promise<Theme[]>
|
|
||||||
call(fnName: 'extras.setTheme', address: string): Promise<boolean>
|
|
||||||
// catchall: ----------------------------------------------------------
|
|
||||||
call(fnName: string): Promise<any>
|
|
||||||
call(fnName: string, ...args: any[]): Promise<any> {
|
|
||||||
return _callDcMethodAsync(fnName, ...args)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const DeltaBackend = new DeltaRemote()
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
after that, or while doing it adjust api to be more complete
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
TODO different test to simulate two devices:
|
|
||||||
|
|
||||||
to test autocrypt_initiate_key_transfer & autocrypt_continue_key_transfer
|
|
||||||
|
|||||||
Reference in New Issue
Block a user