diff --git a/src/ic_panda_frontend/src/lib/canisters/messagechannel.ts b/src/ic_panda_frontend/src/lib/canisters/messagechannel.ts index aed3618..bf48dda 100644 --- a/src/ic_panda_frontend/src/lib/canisters/messagechannel.ts +++ b/src/ic_panda_frontend/src/lib/canisters/messagechannel.ts @@ -6,6 +6,7 @@ import { type ChannelInfo, type ChannelSetting, type Message, + type StateInfo, type UpdateChannelInput, type UpdateChannelMemberInput, type UpdateMySettingInput, @@ -22,6 +23,7 @@ export { type ChannelInfo, type ChannelSetting, type Message, + type StateInfo, type UpdateChannelInput } from '$declarations/ic_message_channel/ic_message_channel.did.js' @@ -79,6 +81,11 @@ export class ChannelAPI { this.actor = actor } + async get_state(): Promise { + const res = await this.actor.get_state() + return unwrapResult(res, 'call get_state failed') + } + async add_message(input: AddMessageInput): Promise { const res = await this.actor.add_message(input) return unwrapResult(res, 'call add_message failed') diff --git a/src/ic_panda_frontend/src/lib/components/core/LuckyPoolChart.svelte b/src/ic_panda_frontend/src/lib/components/core/LuckyPoolChart.svelte index b1a9d1b..9ef04cb 100644 --- a/src/ic_panda_frontend/src/lib/components/core/LuckyPoolChart.svelte +++ b/src/ic_panda_frontend/src/lib/components/core/LuckyPoolChart.svelte @@ -8,7 +8,7 @@ import { authStore } from '$lib/stores/auth' import { shortId } from '$lib/utils/auth' import { formatNumber, ICPToken, PANDAToken } from '$lib/utils/token' - import { isOnline, isVisible } from '$lib/utils/window' + import { isActive } from '$lib/utils/window' import { ProgressBar, Tab, TabGroup, Table } from '@skeletonlabs/skeleton' import { onMount } from 'svelte' import { type Readable } from 'svelte/store' @@ -74,7 +74,7 @@ while (interval) { await new Promise((res) => setTimeout(res, ms)) - if (isOnline() && isVisible()) { + if (isActive()) { await luckyPoolAPI?.refreshAllState() } } diff --git a/src/ic_panda_frontend/src/lib/components/messages/ChannelCreateModel.svelte b/src/ic_panda_frontend/src/lib/components/messages/ChannelCreateModel.svelte index 8dd86be..97a35c3 100644 --- a/src/ic_panda_frontend/src/lib/components/messages/ChannelCreateModel.svelte +++ b/src/ic_panda_frontend/src/lib/components/messages/ChannelCreateModel.svelte @@ -152,7 +152,7 @@ maxHeight="120" class="textarea rounded-xl border-gray/10 bg-white/20 hover:bg-white/90" name="descriptionInput" - placeholder="Channel description..." + placeholder="Channel description (not encrypted)..." />
@@ -165,14 +165,7 @@ 2. A channel can have up to 5 managers and 100 members.

- 3. The channel can store up to 10,000 messages. Once the limit is - reached, old messages must be deleted to send new ones. -

-

- 4. Each message can be up to 32 KB in size. -

-

- 5. Managers can only remove regular members, not other managers. If + 3. Managers can only remove regular members, not other managers. If the last manager leaves, the channel and all messages will be deleted.

diff --git a/src/ic_panda_frontend/src/lib/components/messages/ChannelMessages.svelte b/src/ic_panda_frontend/src/lib/components/messages/ChannelMessages.svelte index 06daa0d..ec08c17 100644 --- a/src/ic_panda_frontend/src/lib/components/messages/ChannelMessages.svelte +++ b/src/ic_panda_frontend/src/lib/components/messages/ChannelMessages.svelte @@ -13,7 +13,7 @@ encodeCBOR, type AesGcmKey } from '$lib/utils/crypto' - import { scrollOnHooks } from '$lib/utils/window' + import { isActive, scrollOnHooks } from '$lib/utils/window' import { getCurrentTimeString, toDisplayUserInfo, @@ -197,7 +197,8 @@ canister, id, dek, - latestMessageId + 1 + latestMessageId + 1, + isActive ) } } @@ -293,13 +294,13 @@
{#each $messageFeed as msg (msg.id)} @@ -319,7 +320,7 @@ {msg.created_time}
lastRead ? 'shadow-md shadow-gold' : ''} {msg.kind === 1 @@ -349,7 +350,7 @@ {msg.created_time}
-
+
-
+
+
+ Messages: + {channelInfo.latest_message_id - channelInfo.message_start + 1} +
+
+ Gas Balance: + {channelInfo.gas} +
+
+
My Setting

Mute notifications:

@@ -311,11 +323,11 @@

Leave channel:

@@ -342,7 +354,7 @@ > {/if}
-
+
Members {#if isManager} diff --git a/src/ic_panda_frontend/src/lib/components/messages/Home.svelte b/src/ic_panda_frontend/src/lib/components/messages/Home.svelte index 7820b0c..62ff409 100644 --- a/src/ic_panda_frontend/src/lib/components/messages/Home.svelte +++ b/src/ic_panda_frontend/src/lib/components/messages/Home.svelte @@ -7,6 +7,7 @@ type MyMessageState } from '$src/lib/stores/message' import { getModalStore, getToastStore } from '@skeletonlabs/skeleton' + import { onMount, tick } from 'svelte' import { type Readable } from 'svelte/store' import UserRegisterModel from './UserRegisterModel.svelte' @@ -16,11 +17,15 @@ const toastStore = getToastStore() const modalStore = getModalStore() + let users_total = 0n + let names_total = 0n + let channels_total = 0n + let messages_total = 0n + function getStartedHandler() { toastRun(async () => { if (myState?.principal.isAnonymous()) { const res = await signIn({}) - myState = await myMessageStateAsync() myInfo = myState.info if (!$myInfo && res.success == 'ok') { modalStore.trigger({ @@ -42,53 +47,112 @@ } }, toastStore) } + + onMount(() => { + const { abort } = toastRun(async () => { + if (!myState) { + myState = await myMessageStateAsync() + } + + users_total = myState.api.state?.users_total || 0n + names_total = myState.api.state?.names_total || 0n + await tick() + + const ids = myState.api.state?.channel_canisters || [] + const states = await Promise.all( + ids.map(async (id) => { + const api = await myState!.api.channelAPI(id) + return await api.get_state() + }) + ) + + channels_total = states.reduce((acc, state) => { + return acc + (state.channels_total || 0n) + }, 0n) + messages_total = states.reduce((acc, state) => { + return acc + (state.messages_total || 0n) + }, 0n) + }, toastStore) + return abort + })
-

- ICPanda Message is a decentralized end-to-end encrypted messaging - application fully running on the - Internet Computer - blockchain. Key features: -

-
    -
  • End-to-end encryption: All user messages are encrypted using the - RFC 9052 (COSE) standard on the client side and stored on the ICP blockchain. These messages - can only be decrypted on the client side.
  • -
  • Multi-user chats: Message channels support one-to-many chats, where - a manager can add or remove members and exchange encryption keys. If the last - manager leaves the channel, all messages in the channel are deleted.
  • -
  • On-chain: It operates entirely as a smart contract on the ICP - blockchain, controlled by - +

    + ICPanda Message is a decentralized end-to-end encrypted messaging + application fully running on the ICPanda DAO, with fully open-source code. It is a trustworthy, secure, verifiable, - and unstoppable Web3 application.

  • + Internet Computer + blockchain. Key features: +

    +
      +
    • End-to-end encryption: All user messages are encrypted using the + RFC 9052 (COSE) standard on the client side and stored on the ICP blockchain. These messages + can only be decrypted on the client side.
    • +
    • Multi-user chats: Message channels support one-to-many chats, where + a manager can add or remove members and exchange encryption keys. If the + last manager leaves the channel, all messages in the channel are deleted.
    • +
    • On-chain: It operates entirely as a smart contract on the ICP + blockchain, controlled by + ICPanda DAO, with fully open-source code. It is a trustworthy, secure, verifiable, + and unstoppable Web3 application.
    • +
    +
+
+
-
- +
+
- Get started - +
+

+ Users: + {users_total} +

+
+ +
+

+ Names: + {names_total} +

+
+
+

+ Channels: + {channels_total} +

+
+
+

+ Messages: + {messages_total} +

+
+
diff --git a/src/ic_panda_frontend/src/lib/components/messages/Index.svelte b/src/ic_panda_frontend/src/lib/components/messages/Index.svelte index c6d65af..8d0ca3b 100644 --- a/src/ic_panda_frontend/src/lib/components/messages/Index.svelte +++ b/src/ic_panda_frontend/src/lib/components/messages/Index.svelte @@ -22,7 +22,7 @@ async function initState() { myState = await myMessageStateAsync() - await myState.refreshState() + await myState.refreshAllState() myInfo = myState.info myInfo_ = myInfo as Readable if ($myInfo) { diff --git a/src/ic_panda_frontend/src/lib/components/messages/MyChannelList.svelte b/src/ic_panda_frontend/src/lib/components/messages/MyChannelList.svelte index 814fbf1..4e41cc2 100644 --- a/src/ic_panda_frontend/src/lib/components/messages/MyChannelList.svelte +++ b/src/ic_panda_frontend/src/lib/components/messages/MyChannelList.svelte @@ -4,6 +4,7 @@ import IconAdd from '$lib/components/icons/IconAdd.svelte' import IconNotificationOffLine from '$lib/components/icons/IconNotificationOffLine.svelte' import { toastRun } from '$lib/stores/toast' + import { isActive } from '$lib/utils/window' import { myMessageStateAsync, type ChannelBasicInfoEx, @@ -45,7 +46,7 @@ return } - myState.refreshMyChannels(signal) + isActive() && myState.refreshMyChannels(signal) }, 10000) }, toastStore) return abort diff --git a/src/ic_panda_frontend/src/lib/components/messages/PasswordModel.svelte b/src/ic_panda_frontend/src/lib/components/messages/PasswordModel.svelte index 5570a35..be51c86 100644 --- a/src/ic_panda_frontend/src/lib/components/messages/PasswordModel.svelte +++ b/src/ic_panda_frontend/src/lib/components/messages/PasswordModel.svelte @@ -148,25 +148,8 @@ class="m-auto !mt-4 flex flex-col content-center" on:input|preventDefault|stopPropagation={onFormChange} > - {#if isSetup} -
-

- The password is used only locally to derive the master key with remote - key material; neither the password nor the derived key is stored - remotely. -

-

- It is recommended to use - simple and easy-to-remember passwords. -

-

- If you forget the password, you will no longer be able to decrypt the - messages! -

-
- {/if} {passwordTip}

+ {#if isSetup} +
+
+

+ 1. The password is used only locally to derive the master key with + remote key material; neither the password nor the derived key is stored + remotely. +

+

+ 2. It is recommended to use + simple and easy-to-remember passwords. +

+

+ 3. If you forget the password, you will no longer be able to decrypt + the messages! +

+
+ {/if}