{message}
} 12 |{t('You have been muted by an admin and cannot send messages.')}
11 | > 12 | ); 13 | }; 14 | 15 | export default UserWasMuted; 16 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | NEXT_TELEMETRY_DISABLED=1 2 | NEXT_PUBLIC_APP_VERSION=$npm_package_version 3 | NEXT_PUBLIC_APP_GOOGLE_DRIVE_CLIENT_ID= 4 | NEXT_PUBLIC_APP_DROPBOX_CLIENT_ID= 5 | NEXT_PUBLIC_APP_GENERAL_CHAT_LINK=https://haven.xx.network/join 6 | # DFX CANISTER ENVIRONMENT VARIABLES 7 | DFX_VERSION='0.24.0' 8 | DFX_NETWORK='ic' 9 | CANISTER_ID_APP='' 10 | CANISTER_ID='' 11 | CANISTER_CANDID_PATH='/path/to/haven/.dfx/ic/canisters/app/assetstorage.did' 12 | # END DFX CANISTER ENVIRONMENT VARIABLES 13 | -------------------------------------------------------------------------------- /src/hooks/useChannelsStorageTag.ts: -------------------------------------------------------------------------------- 1 | import { JsonDecoder } from 'ts.data.json'; 2 | import useRemotelySynchedValue from './useRemotelySynchedValue'; 3 | import { makeDecoder } from '@utils/decoders'; 4 | 5 | const KEY = 'channels-storage-tag'; 6 | 7 | const useStorageTag = () => { 8 | const result = useRemotelySynchedValue(KEY, makeDecoder(JsonDecoder.string)); 9 | console.log('Ready storage tag value:', result.value); 10 | return result; 11 | }; 12 | 13 | export default useStorageTag; 14 | -------------------------------------------------------------------------------- /src/router.tsx: -------------------------------------------------------------------------------- 1 | import { createBrowserRouter } from 'react-router-dom'; 2 | import Home from './routes/Home'; 3 | import Join from './routes/Join'; 4 | import App from './App'; 5 | 6 | export const router = createBrowserRouter([ 7 | { 8 | path: '/', 9 | element:Connecting to the network...
12 |16 | {t('The network is not ready to send messages yet. Please try again in a few seconds.')} 17 |
18 | 21 | > 22 | ); 23 | }; 24 | 25 | export default NetworkNotReadyView; 26 | -------------------------------------------------------------------------------- /src/components/common/Badge.tsx: -------------------------------------------------------------------------------- 1 | import React, { FC, HTMLAttributes } from 'react'; 2 | 3 | type Props = HTMLAttributes{error.message}
18 | 23 | [{t('There are currently no pinned messages in this channel')}] 24 |
25 | )} 26 | {pinnedMessages &&27 | ** {t('Important to note that deleting messages cannot be undone.')} ** 28 |
29 |17 | {t( 18 | "Warning: By logging out, all of you current data will be deleted from your browser. Please make sure you have a backup first. This can't be undone." 19 | )} 20 |
21 | 38 | > 39 | ); 40 | }; 41 | 42 | export default LogOutView; 43 | -------------------------------------------------------------------------------- /src/components/icons/Spaces.tsx: -------------------------------------------------------------------------------- 1 | import { SVGProps } from 'react'; 2 | 3 | const Spaces = (props: SVGProps31 | {t(`Pinned messages will remain for around 3 weeks, then it will 32 | get unpinned again`)} 33 |
34 |28 | ** {t('Important to note that muting users cannot be undone.')} ** 29 |
30 |33 | {t('Are you sure you would like to leave this space?')} 34 |
35 | 38 | > 39 | ); 40 | }; 41 | 42 | export default LeaveChannelConfirmationView; 43 | -------------------------------------------------------------------------------- /src/types/emitter.ts: -------------------------------------------------------------------------------- 1 | export type EventMap = { 2 | [key: string]: (...args: any[]) => void; 3 | }; 4 | 5 | /** 6 | * Type-safe event emitter. 7 | * 8 | * Use it like this: 9 | * 10 | * ```typescript 11 | * type MyEvents = { 12 | * error: (error: Error) => void; 13 | * message: (from: string, content: string) => void; 14 | * } 15 | * 16 | * const myEmitter = new EventEmitter() as TypedEmitter29 | Sync your account with multiple devices using the cloud with account sync. The file is 30 | encrypted so there are no privacy concerns with using these third party services. 31 |
32 |33 | Warning! Once you choose a cloud provider you will not be able to change to 34 | another service or revert to local-only. 35 |
36 | {loading ? ( 37 |{content}
47 | {description &&{description}
} 48 |37 | {t('You can export your codename for backup or to use your codename on a second device.')} 38 |
39 | 49 | > 50 | ); 51 | }; 52 | 53 | export default ExportCodenameView; 54 | -------------------------------------------------------------------------------- /src/components/icons/OrderedList.tsx: -------------------------------------------------------------------------------- 1 | import { SVGProps } from 'react'; 2 | 3 | const OrderedList = (props: SVGProps