mirror of
https://github.com/cinnyapp/cinny.git
synced 2025-11-04 22:40:29 +03:00
Merge branch 'dev' into start-thread-button
This commit is contained in:
commit
1bba6af561
22 changed files with 452 additions and 46 deletions
2
.github/workflows/build-pull-request.yml
vendored
2
.github/workflows/build-pull-request.yml
vendored
|
|
@ -14,7 +14,7 @@ jobs:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4.2.0
|
uses: actions/checkout@v4.2.0
|
||||||
- name: Setup node
|
- name: Setup node
|
||||||
uses: actions/setup-node@v4.3.0
|
uses: actions/setup-node@v4.4.0
|
||||||
with:
|
with:
|
||||||
node-version: 20.12.2
|
node-version: 20.12.2
|
||||||
cache: 'npm'
|
cache: 'npm'
|
||||||
|
|
|
||||||
2
.github/workflows/docker-pr.yml
vendored
2
.github/workflows/docker-pr.yml
vendored
|
|
@ -13,7 +13,7 @@ jobs:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4.2.0
|
uses: actions/checkout@v4.2.0
|
||||||
- name: Build Docker image
|
- name: Build Docker image
|
||||||
uses: docker/build-push-action@v6.15.0
|
uses: docker/build-push-action@v6.18.0
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
push: false
|
push: false
|
||||||
|
|
|
||||||
2
.github/workflows/netlify-dev.yml
vendored
2
.github/workflows/netlify-dev.yml
vendored
|
|
@ -13,7 +13,7 @@ jobs:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4.2.0
|
uses: actions/checkout@v4.2.0
|
||||||
- name: Setup node
|
- name: Setup node
|
||||||
uses: actions/setup-node@v4.3.0
|
uses: actions/setup-node@v4.4.0
|
||||||
with:
|
with:
|
||||||
node-version: 20.12.2
|
node-version: 20.12.2
|
||||||
cache: 'npm'
|
cache: 'npm'
|
||||||
|
|
|
||||||
4
.github/workflows/prod-deploy.yml
vendored
4
.github/workflows/prod-deploy.yml
vendored
|
|
@ -12,7 +12,7 @@ jobs:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4.2.0
|
uses: actions/checkout@v4.2.0
|
||||||
- name: Setup node
|
- name: Setup node
|
||||||
uses: actions/setup-node@v4.3.0
|
uses: actions/setup-node@v4.4.0
|
||||||
with:
|
with:
|
||||||
node-version: 20.12.2
|
node-version: 20.12.2
|
||||||
cache: 'npm'
|
cache: 'npm'
|
||||||
|
|
@ -90,7 +90,7 @@ jobs:
|
||||||
${{ secrets.DOCKER_USERNAME }}/cinny
|
${{ secrets.DOCKER_USERNAME }}/cinny
|
||||||
ghcr.io/${{ github.repository }}
|
ghcr.io/${{ github.repository }}
|
||||||
- name: Build and push Docker image
|
- name: Build and push Docker image
|
||||||
uses: docker/build-push-action@v6.15.0
|
uses: docker/build-push-action@v6.18.0
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
|
|
|
||||||
4
package-lock.json
generated
4
package-lock.json
generated
|
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "cinny",
|
"name": "cinny",
|
||||||
"version": "4.8.0",
|
"version": "4.8.1",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "cinny",
|
"name": "cinny",
|
||||||
"version": "4.8.0",
|
"version": "4.8.1",
|
||||||
"license": "AGPL-3.0-only",
|
"license": "AGPL-3.0-only",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@atlaskit/pragmatic-drag-and-drop": "1.1.6",
|
"@atlaskit/pragmatic-drag-and-drop": "1.1.6",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "cinny",
|
"name": "cinny",
|
||||||
"version": "4.8.0",
|
"version": "4.8.1",
|
||||||
"description": "Yet another matrix client",
|
"description": "Yet another matrix client",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import React, { useCallback, useMemo } from 'react';
|
||||||
import { color, Text } from 'folds';
|
import { color, Text } from 'folds';
|
||||||
import { JoinRule, MatrixError, RestrictedAllowType } from 'matrix-js-sdk';
|
import { JoinRule, MatrixError, RestrictedAllowType } from 'matrix-js-sdk';
|
||||||
import { RoomJoinRulesEventContent } from 'matrix-js-sdk/lib/types';
|
import { RoomJoinRulesEventContent } from 'matrix-js-sdk/lib/types';
|
||||||
|
import { useAtomValue } from 'jotai';
|
||||||
import { IPowerLevels, powerLevelAPI } from '../../../hooks/usePowerLevels';
|
import { IPowerLevels, powerLevelAPI } from '../../../hooks/usePowerLevels';
|
||||||
import {
|
import {
|
||||||
ExtendedJoinRules,
|
ExtendedJoinRules,
|
||||||
|
|
@ -20,6 +21,12 @@ import { useStateEvent } from '../../../hooks/useStateEvent';
|
||||||
import { useSpaceOptionally } from '../../../hooks/useSpace';
|
import { useSpaceOptionally } from '../../../hooks/useSpace';
|
||||||
import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback';
|
import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback';
|
||||||
import { getStateEvents } from '../../../utils/room';
|
import { getStateEvents } from '../../../utils/room';
|
||||||
|
import {
|
||||||
|
useRecursiveChildSpaceScopeFactory,
|
||||||
|
useSpaceChildren,
|
||||||
|
} from '../../../state/hooks/roomList';
|
||||||
|
import { allRoomsAtom } from '../../../state/room-list/roomList';
|
||||||
|
import { roomToParentsAtom } from '../../../state/room/roomToParents';
|
||||||
|
|
||||||
type RestrictedRoomAllowContent = {
|
type RestrictedRoomAllowContent = {
|
||||||
room_id: string;
|
room_id: string;
|
||||||
|
|
@ -36,7 +43,11 @@ export function RoomJoinRules({ powerLevels }: RoomJoinRulesProps) {
|
||||||
const allowKnockRestricted = roomVersion >= 10;
|
const allowKnockRestricted = roomVersion >= 10;
|
||||||
const allowRestricted = roomVersion >= 8;
|
const allowRestricted = roomVersion >= 8;
|
||||||
const allowKnock = roomVersion >= 7;
|
const allowKnock = roomVersion >= 7;
|
||||||
|
|
||||||
|
const roomIdToParents = useAtomValue(roomToParentsAtom);
|
||||||
const space = useSpaceOptionally();
|
const space = useSpaceOptionally();
|
||||||
|
const subspacesScope = useRecursiveChildSpaceScopeFactory(mx, roomIdToParents);
|
||||||
|
const subspaces = useSpaceChildren(allRoomsAtom, space?.roomId ?? '', subspacesScope);
|
||||||
|
|
||||||
const userPowerLevel = powerLevelAPI.getPowerLevel(powerLevels, mx.getSafeUserId());
|
const userPowerLevel = powerLevelAPI.getPowerLevel(powerLevels, mx.getSafeUserId());
|
||||||
const canEdit = powerLevelAPI.canSendStateEvent(
|
const canEdit = powerLevelAPI.canSendStateEvent(
|
||||||
|
|
@ -74,9 +85,22 @@ export function RoomJoinRules({ powerLevels }: RoomJoinRulesProps) {
|
||||||
async (joinRule: ExtendedJoinRules) => {
|
async (joinRule: ExtendedJoinRules) => {
|
||||||
const allow: RestrictedRoomAllowContent[] = [];
|
const allow: RestrictedRoomAllowContent[] = [];
|
||||||
if (joinRule === JoinRule.Restricted || joinRule === 'knock_restricted') {
|
if (joinRule === JoinRule.Restricted || joinRule === 'knock_restricted') {
|
||||||
const parents = getStateEvents(room, StateEvent.SpaceParent).map((event) =>
|
const roomParents = roomIdToParents.get(room.roomId);
|
||||||
event.getStateKey()
|
|
||||||
);
|
const parents = getStateEvents(room, StateEvent.SpaceParent)
|
||||||
|
.map((event) => event.getStateKey())
|
||||||
|
.filter((parentId) => typeof parentId === 'string')
|
||||||
|
.filter((parentId) => roomParents?.has(parentId));
|
||||||
|
|
||||||
|
if (parents.length === 0 && space && roomParents) {
|
||||||
|
// if no m.space.parent found
|
||||||
|
// find parent in current space
|
||||||
|
const selectedParents = subspaces.filter((rId) => roomParents.has(rId));
|
||||||
|
if (roomParents.has(space.roomId)) {
|
||||||
|
selectedParents.push(space.roomId);
|
||||||
|
}
|
||||||
|
selectedParents.forEach((pId) => parents.push(pId));
|
||||||
|
}
|
||||||
parents.forEach((parentRoomId) => {
|
parents.forEach((parentRoomId) => {
|
||||||
if (!parentRoomId) return;
|
if (!parentRoomId) return;
|
||||||
allow.push({
|
allow.push({
|
||||||
|
|
@ -92,7 +116,7 @@ export function RoomJoinRules({ powerLevels }: RoomJoinRulesProps) {
|
||||||
if (allow.length > 0) c.allow = allow;
|
if (allow.length > 0) c.allow = allow;
|
||||||
await mx.sendStateEvent(room.roomId, StateEvent.RoomJoinRules as any, c);
|
await mx.sendStateEvent(room.roomId, StateEvent.RoomJoinRules as any, c);
|
||||||
},
|
},
|
||||||
[mx, room]
|
[mx, room, space, subspaces, roomIdToParents]
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ export function SearchInput({ active, loading, searchInputRef, onSearch, onReset
|
||||||
ref={searchInputRef}
|
ref={searchInputRef}
|
||||||
style={{ paddingRight: config.space.S300 }}
|
style={{ paddingRight: config.space.S300 }}
|
||||||
name="searchInput"
|
name="searchInput"
|
||||||
|
autoFocus
|
||||||
size="500"
|
size="500"
|
||||||
variant="Background"
|
variant="Background"
|
||||||
placeholder="Search for keyword"
|
placeholder="Search for keyword"
|
||||||
|
|
|
||||||
|
|
@ -448,6 +448,7 @@ export function RoomTimeline({
|
||||||
const [encUrlPreview] = useSetting(settingsAtom, 'encUrlPreview');
|
const [encUrlPreview] = useSetting(settingsAtom, 'encUrlPreview');
|
||||||
const showUrlPreview = room.hasEncryptionStateEvent() ? encUrlPreview : urlPreview;
|
const showUrlPreview = room.hasEncryptionStateEvent() ? encUrlPreview : urlPreview;
|
||||||
const [showHiddenEvents] = useSetting(settingsAtom, 'showHiddenEvents');
|
const [showHiddenEvents] = useSetting(settingsAtom, 'showHiddenEvents');
|
||||||
|
const [showDeveloperTools] = useSetting(settingsAtom, 'developerTools');
|
||||||
|
|
||||||
const ignoredUsersList = useIgnoredUsers();
|
const ignoredUsersList = useIgnoredUsers();
|
||||||
const ignoredUsersSet = useMemo(() => new Set(ignoredUsersList), [ignoredUsersList]);
|
const ignoredUsersSet = useMemo(() => new Set(ignoredUsersList), [ignoredUsersList]);
|
||||||
|
|
@ -1067,6 +1068,7 @@ export function RoomTimeline({
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
hideReadReceipts={hideActivity}
|
hideReadReceipts={hideActivity}
|
||||||
|
showDeveloperTools={showDeveloperTools}
|
||||||
powerLevelTag={getPowerLevelTag(senderPowerLevel)}
|
powerLevelTag={getPowerLevelTag(senderPowerLevel)}
|
||||||
accessibleTagColors={accessibleTagColors}
|
accessibleTagColors={accessibleTagColors}
|
||||||
legacyUsernameColor={legacyUsernameColor || direct}
|
legacyUsernameColor={legacyUsernameColor || direct}
|
||||||
|
|
@ -1148,6 +1150,7 @@ export function RoomTimeline({
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
hideReadReceipts={hideActivity}
|
hideReadReceipts={hideActivity}
|
||||||
|
showDeveloperTools={showDeveloperTools}
|
||||||
powerLevelTag={getPowerLevelTag(senderPowerLevel)}
|
powerLevelTag={getPowerLevelTag(senderPowerLevel)}
|
||||||
accessibleTagColors={accessibleTagColors}
|
accessibleTagColors={accessibleTagColors}
|
||||||
legacyUsernameColor={legacyUsernameColor || direct}
|
legacyUsernameColor={legacyUsernameColor || direct}
|
||||||
|
|
@ -1249,6 +1252,7 @@ export function RoomTimeline({
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
hideReadReceipts={hideActivity}
|
hideReadReceipts={hideActivity}
|
||||||
|
showDeveloperTools={showDeveloperTools}
|
||||||
powerLevelTag={getPowerLevelTag(senderPowerLevel)}
|
powerLevelTag={getPowerLevelTag(senderPowerLevel)}
|
||||||
accessibleTagColors={accessibleTagColors}
|
accessibleTagColors={accessibleTagColors}
|
||||||
legacyUsernameColor={legacyUsernameColor || direct}
|
legacyUsernameColor={legacyUsernameColor || direct}
|
||||||
|
|
@ -1294,6 +1298,7 @@ export function RoomTimeline({
|
||||||
messageSpacing={messageSpacing}
|
messageSpacing={messageSpacing}
|
||||||
canDelete={canRedact || mEvent.getSender() === mx.getUserId()}
|
canDelete={canRedact || mEvent.getSender() === mx.getUserId()}
|
||||||
hideReadReceipts={hideActivity}
|
hideReadReceipts={hideActivity}
|
||||||
|
showDeveloperTools={showDeveloperTools}
|
||||||
>
|
>
|
||||||
<EventContent
|
<EventContent
|
||||||
messageLayout={messageLayout}
|
messageLayout={messageLayout}
|
||||||
|
|
@ -1330,6 +1335,7 @@ export function RoomTimeline({
|
||||||
messageSpacing={messageSpacing}
|
messageSpacing={messageSpacing}
|
||||||
canDelete={canRedact || mEvent.getSender() === mx.getUserId()}
|
canDelete={canRedact || mEvent.getSender() === mx.getUserId()}
|
||||||
hideReadReceipts={hideActivity}
|
hideReadReceipts={hideActivity}
|
||||||
|
showDeveloperTools={showDeveloperTools}
|
||||||
>
|
>
|
||||||
<EventContent
|
<EventContent
|
||||||
messageLayout={messageLayout}
|
messageLayout={messageLayout}
|
||||||
|
|
@ -1367,6 +1373,7 @@ export function RoomTimeline({
|
||||||
messageSpacing={messageSpacing}
|
messageSpacing={messageSpacing}
|
||||||
canDelete={canRedact || mEvent.getSender() === mx.getUserId()}
|
canDelete={canRedact || mEvent.getSender() === mx.getUserId()}
|
||||||
hideReadReceipts={hideActivity}
|
hideReadReceipts={hideActivity}
|
||||||
|
showDeveloperTools={showDeveloperTools}
|
||||||
>
|
>
|
||||||
<EventContent
|
<EventContent
|
||||||
messageLayout={messageLayout}
|
messageLayout={messageLayout}
|
||||||
|
|
@ -1404,6 +1411,7 @@ export function RoomTimeline({
|
||||||
messageSpacing={messageSpacing}
|
messageSpacing={messageSpacing}
|
||||||
canDelete={canRedact || mEvent.getSender() === mx.getUserId()}
|
canDelete={canRedact || mEvent.getSender() === mx.getUserId()}
|
||||||
hideReadReceipts={hideActivity}
|
hideReadReceipts={hideActivity}
|
||||||
|
showDeveloperTools={showDeveloperTools}
|
||||||
>
|
>
|
||||||
<EventContent
|
<EventContent
|
||||||
messageLayout={messageLayout}
|
messageLayout={messageLayout}
|
||||||
|
|
@ -1443,6 +1451,7 @@ export function RoomTimeline({
|
||||||
messageSpacing={messageSpacing}
|
messageSpacing={messageSpacing}
|
||||||
canDelete={canRedact || mEvent.getSender() === mx.getUserId()}
|
canDelete={canRedact || mEvent.getSender() === mx.getUserId()}
|
||||||
hideReadReceipts={hideActivity}
|
hideReadReceipts={hideActivity}
|
||||||
|
showDeveloperTools={showDeveloperTools}
|
||||||
>
|
>
|
||||||
<EventContent
|
<EventContent
|
||||||
messageLayout={messageLayout}
|
messageLayout={messageLayout}
|
||||||
|
|
@ -1487,6 +1496,7 @@ export function RoomTimeline({
|
||||||
messageSpacing={messageSpacing}
|
messageSpacing={messageSpacing}
|
||||||
canDelete={canRedact || mEvent.getSender() === mx.getUserId()}
|
canDelete={canRedact || mEvent.getSender() === mx.getUserId()}
|
||||||
hideReadReceipts={hideActivity}
|
hideReadReceipts={hideActivity}
|
||||||
|
showDeveloperTools={showDeveloperTools}
|
||||||
>
|
>
|
||||||
<EventContent
|
<EventContent
|
||||||
messageLayout={messageLayout}
|
messageLayout={messageLayout}
|
||||||
|
|
|
||||||
|
|
@ -678,6 +678,7 @@ export type MessageProps = {
|
||||||
reply?: ReactNode;
|
reply?: ReactNode;
|
||||||
reactions?: ReactNode;
|
reactions?: ReactNode;
|
||||||
hideReadReceipts?: boolean;
|
hideReadReceipts?: boolean;
|
||||||
|
showDeveloperTools?: boolean;
|
||||||
powerLevelTag?: PowerLevelTag;
|
powerLevelTag?: PowerLevelTag;
|
||||||
accessibleTagColors?: Map<string, string>;
|
accessibleTagColors?: Map<string, string>;
|
||||||
legacyUsernameColor?: boolean;
|
legacyUsernameColor?: boolean;
|
||||||
|
|
@ -706,6 +707,7 @@ export const Message = as<'div', MessageProps>(
|
||||||
reply,
|
reply,
|
||||||
reactions,
|
reactions,
|
||||||
hideReadReceipts,
|
hideReadReceipts,
|
||||||
|
showDeveloperTools,
|
||||||
powerLevelTag,
|
powerLevelTag,
|
||||||
accessibleTagColors,
|
accessibleTagColors,
|
||||||
legacyUsernameColor,
|
legacyUsernameColor,
|
||||||
|
|
@ -1042,7 +1044,13 @@ export const Message = as<'div', MessageProps>(
|
||||||
onClose={closeMenu}
|
onClose={closeMenu}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<MessageSourceCodeItem room={room} mEvent={mEvent} onClose={closeMenu} />
|
{showDeveloperTools && (
|
||||||
|
<MessageSourceCodeItem
|
||||||
|
room={room}
|
||||||
|
mEvent={mEvent}
|
||||||
|
onClose={closeMenu}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
<MessageCopyLinkItem room={room} mEvent={mEvent} onClose={closeMenu} />
|
<MessageCopyLinkItem room={room} mEvent={mEvent} onClose={closeMenu} />
|
||||||
{canPinEvent && (
|
{canPinEvent && (
|
||||||
<MessagePinItem room={room} mEvent={mEvent} onClose={closeMenu} />
|
<MessagePinItem room={room} mEvent={mEvent} onClose={closeMenu} />
|
||||||
|
|
@ -1117,6 +1125,7 @@ export type EventProps = {
|
||||||
canDelete?: boolean;
|
canDelete?: boolean;
|
||||||
messageSpacing: MessageSpacing;
|
messageSpacing: MessageSpacing;
|
||||||
hideReadReceipts?: boolean;
|
hideReadReceipts?: boolean;
|
||||||
|
showDeveloperTools?: boolean;
|
||||||
};
|
};
|
||||||
export const Event = as<'div', EventProps>(
|
export const Event = as<'div', EventProps>(
|
||||||
(
|
(
|
||||||
|
|
@ -1128,6 +1137,7 @@ export const Event = as<'div', EventProps>(
|
||||||
canDelete,
|
canDelete,
|
||||||
messageSpacing,
|
messageSpacing,
|
||||||
hideReadReceipts,
|
hideReadReceipts,
|
||||||
|
showDeveloperTools,
|
||||||
children,
|
children,
|
||||||
...props
|
...props
|
||||||
},
|
},
|
||||||
|
|
@ -1204,7 +1214,13 @@ export const Event = as<'div', EventProps>(
|
||||||
onClose={closeMenu}
|
onClose={closeMenu}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<MessageSourceCodeItem room={room} mEvent={mEvent} onClose={closeMenu} />
|
{showDeveloperTools && (
|
||||||
|
<MessageSourceCodeItem
|
||||||
|
room={room}
|
||||||
|
mEvent={mEvent}
|
||||||
|
onClose={closeMenu}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
<MessageCopyLinkItem room={room} mEvent={mEvent} onClose={closeMenu} />
|
<MessageCopyLinkItem room={room} mEvent={mEvent} onClose={closeMenu} />
|
||||||
</Box>
|
</Box>
|
||||||
{((!mEvent.isRedacted() && canDelete && !stateEvent) ||
|
{((!mEvent.isRedacted() && canDelete && !stateEvent) ||
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@ import { getOrphanParents } from '../utils/room';
|
||||||
import { roomToParentsAtom } from '../state/room/roomToParents';
|
import { roomToParentsAtom } from '../state/room/roomToParents';
|
||||||
import { mDirectAtom } from '../state/mDirectList';
|
import { mDirectAtom } from '../state/mDirectList';
|
||||||
import { useSelectedSpace } from './router/useSelectedSpace';
|
import { useSelectedSpace } from './router/useSelectedSpace';
|
||||||
|
import { settingsAtom } from '../state/settings';
|
||||||
|
import { useSetting } from '../state/hooks/settings';
|
||||||
|
|
||||||
export const useRoomNavigate = () => {
|
export const useRoomNavigate = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
@ -20,6 +22,7 @@ export const useRoomNavigate = () => {
|
||||||
const roomToParents = useAtomValue(roomToParentsAtom);
|
const roomToParents = useAtomValue(roomToParentsAtom);
|
||||||
const mDirects = useAtomValue(mDirectAtom);
|
const mDirects = useAtomValue(mDirectAtom);
|
||||||
const spaceSelectedId = useSelectedSpace();
|
const spaceSelectedId = useSelectedSpace();
|
||||||
|
const [developerTools] = useSetting(settingsAtom, 'developerTools');
|
||||||
|
|
||||||
const navigateSpace = useCallback(
|
const navigateSpace = useCallback(
|
||||||
(roomId: string) => {
|
(roomId: string) => {
|
||||||
|
|
@ -32,15 +35,22 @@ export const useRoomNavigate = () => {
|
||||||
const navigateRoom = useCallback(
|
const navigateRoom = useCallback(
|
||||||
(roomId: string, eventId?: string, opts?: NavigateOptions) => {
|
(roomId: string, eventId?: string, opts?: NavigateOptions) => {
|
||||||
const roomIdOrAlias = getCanonicalAliasOrRoomId(mx, roomId);
|
const roomIdOrAlias = getCanonicalAliasOrRoomId(mx, roomId);
|
||||||
|
const openSpaceTimeline = developerTools && spaceSelectedId === roomId;
|
||||||
|
|
||||||
const orphanParents = getOrphanParents(roomToParents, roomId);
|
const orphanParents = openSpaceTimeline ? [roomId] : getOrphanParents(roomToParents, roomId);
|
||||||
if (orphanParents.length > 0) {
|
if (orphanParents.length > 0) {
|
||||||
const pSpaceIdOrAlias = getCanonicalAliasOrRoomId(
|
const pSpaceIdOrAlias = getCanonicalAliasOrRoomId(
|
||||||
mx,
|
mx,
|
||||||
spaceSelectedId && orphanParents.includes(spaceSelectedId)
|
spaceSelectedId && orphanParents.includes(spaceSelectedId)
|
||||||
? spaceSelectedId
|
? spaceSelectedId
|
||||||
: orphanParents[0]
|
: orphanParents[0] // TODO: better orphan parent selection.
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (openSpaceTimeline) {
|
||||||
|
navigate(getSpaceRoomPath(pSpaceIdOrAlias, roomId, eventId), opts);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
navigate(getSpaceRoomPath(pSpaceIdOrAlias, roomIdOrAlias, eventId), opts);
|
navigate(getSpaceRoomPath(pSpaceIdOrAlias, roomIdOrAlias, eventId), opts);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -52,7 +62,7 @@ export const useRoomNavigate = () => {
|
||||||
|
|
||||||
navigate(getHomeRoomPath(roomIdOrAlias, eventId), opts);
|
navigate(getHomeRoomPath(roomIdOrAlias, eventId), opts);
|
||||||
},
|
},
|
||||||
[mx, navigate, spaceSelectedId, roomToParents, mDirects]
|
[mx, navigate, spaceSelectedId, roomToParents, mDirects, developerTools]
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
|
|
@ -273,7 +273,7 @@ function InviteUser({ isOpen, roomId, searchTerm, onRequestClose }) {
|
||||||
searchUser(usernameRef.current.value);
|
searchUser(usernameRef.current.value);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Input value={searchTerm} forwardRef={usernameRef} label="Name or userId" />
|
<Input value={searchTerm} forwardRef={usernameRef} label="Name or userId" autoFocus />
|
||||||
<Button disabled={isSearching} iconSrc={UserIC} variant="primary" type="submit">
|
<Button disabled={isSearching} iconSrc={UserIC} variant="primary" type="submit">
|
||||||
Search
|
Search
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ function JoinAliasContent({ term, requestClose }) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form className="join-alias" onSubmit={handleSubmit}>
|
<form className="join-alias" onSubmit={handleSubmit}>
|
||||||
<Input label="Address" value={term} name="alias" required />
|
<Input label="Address" value={term} name="alias" required autoFocus />
|
||||||
{error && (
|
{error && (
|
||||||
<Text className="join-alias__error" variant="b3">
|
<Text className="join-alias__error" variant="b3">
|
||||||
{error}
|
{error}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ export function AuthFooter() {
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
>
|
>
|
||||||
v4.8.0
|
v4.8.1
|
||||||
</Text>
|
</Text>
|
||||||
<Text as="a" size="T300" href="https://twitter.com/cinnyapp" target="_blank" rel="noreferrer">
|
<Text as="a" size="T300" href="https://twitter.com/cinnyapp" target="_blank" rel="noreferrer">
|
||||||
Twitter
|
Twitter
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ export function WelcomePage() {
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noreferrer noopener"
|
rel="noreferrer noopener"
|
||||||
>
|
>
|
||||||
v4.8.0
|
v4.8.1
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -744,13 +744,14 @@ export function SpaceTabs({ scrollRef }: SpaceTabsProps) {
|
||||||
const targetSpaceId = target.getAttribute('data-id');
|
const targetSpaceId = target.getAttribute('data-id');
|
||||||
if (!targetSpaceId) return;
|
if (!targetSpaceId) return;
|
||||||
|
|
||||||
|
const spacePath = getSpacePath(getCanonicalAliasOrRoomId(mx, targetSpaceId));
|
||||||
if (screenSize === ScreenSize.Mobile) {
|
if (screenSize === ScreenSize.Mobile) {
|
||||||
navigate(getSpacePath(getCanonicalAliasOrRoomId(mx, targetSpaceId)));
|
navigate(spacePath);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const activePath = navToActivePath.get(targetSpaceId);
|
const activePath = navToActivePath.get(targetSpaceId);
|
||||||
if (activePath) {
|
if (activePath && activePath.pathname.startsWith(spacePath)) {
|
||||||
navigate(joinPathComponent(activePath));
|
navigate(joinPathComponent(activePath));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,24 @@
|
||||||
import React, { ReactNode } from 'react';
|
import React, { ReactNode } from 'react';
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
import { useAtomValue } from 'jotai';
|
import { useAtom, useAtomValue } from 'jotai';
|
||||||
import { useSelectedRoom } from '../../../hooks/router/useSelectedRoom';
|
import { useSelectedRoom } from '../../../hooks/router/useSelectedRoom';
|
||||||
import { IsDirectRoomProvider, RoomProvider } from '../../../hooks/useRoom';
|
import { IsDirectRoomProvider, RoomProvider } from '../../../hooks/useRoom';
|
||||||
import { useMatrixClient } from '../../../hooks/useMatrixClient';
|
import { useMatrixClient } from '../../../hooks/useMatrixClient';
|
||||||
import { JoinBeforeNavigate } from '../../../features/join-before-navigate';
|
import { JoinBeforeNavigate } from '../../../features/join-before-navigate';
|
||||||
import { useSpace } from '../../../hooks/useSpace';
|
import { useSpace } from '../../../hooks/useSpace';
|
||||||
import { getAllParents } from '../../../utils/room';
|
import { getAllParents, getSpaceChildren } from '../../../utils/room';
|
||||||
import { roomToParentsAtom } from '../../../state/room/roomToParents';
|
import { roomToParentsAtom } from '../../../state/room/roomToParents';
|
||||||
import { allRoomsAtom } from '../../../state/room-list/roomList';
|
import { allRoomsAtom } from '../../../state/room-list/roomList';
|
||||||
import { useSearchParamsViaServers } from '../../../hooks/router/useSearchParamsViaServers';
|
import { useSearchParamsViaServers } from '../../../hooks/router/useSearchParamsViaServers';
|
||||||
import { mDirectAtom } from '../../../state/mDirectList';
|
import { mDirectAtom } from '../../../state/mDirectList';
|
||||||
|
import { settingsAtom } from '../../../state/settings';
|
||||||
|
import { useSetting } from '../../../state/hooks/settings';
|
||||||
|
|
||||||
export function SpaceRouteRoomProvider({ children }: { children: ReactNode }) {
|
export function SpaceRouteRoomProvider({ children }: { children: ReactNode }) {
|
||||||
const mx = useMatrixClient();
|
const mx = useMatrixClient();
|
||||||
const space = useSpace();
|
const space = useSpace();
|
||||||
const roomToParents = useAtomValue(roomToParentsAtom);
|
const [developerTools] = useSetting(settingsAtom, 'developerTools');
|
||||||
|
const [roomToParents, setRoomToParents] = useAtom(roomToParentsAtom);
|
||||||
const mDirects = useAtomValue(mDirectAtom);
|
const mDirects = useAtomValue(mDirectAtom);
|
||||||
const allRooms = useAtomValue(allRoomsAtom);
|
const allRooms = useAtomValue(allRoomsAtom);
|
||||||
|
|
||||||
|
|
@ -24,12 +27,36 @@ export function SpaceRouteRoomProvider({ children }: { children: ReactNode }) {
|
||||||
const roomId = useSelectedRoom();
|
const roomId = useSelectedRoom();
|
||||||
const room = mx.getRoom(roomId);
|
const room = mx.getRoom(roomId);
|
||||||
|
|
||||||
if (
|
if (!room || !allRooms.includes(room.roomId)) {
|
||||||
!room ||
|
// room is not joined
|
||||||
room.isSpaceRoom() ||
|
return (
|
||||||
!allRooms.includes(room.roomId) ||
|
<JoinBeforeNavigate
|
||||||
!getAllParents(roomToParents, room.roomId).has(space.roomId)
|
roomIdOrAlias={roomIdOrAlias!}
|
||||||
) {
|
eventId={eventId}
|
||||||
|
viaServers={viaServers}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (developerTools && room.isSpaceRoom() && room.roomId === space.roomId) {
|
||||||
|
// allow to view space timeline
|
||||||
|
return (
|
||||||
|
<RoomProvider key={room.roomId} value={room}>
|
||||||
|
<IsDirectRoomProvider value={mDirects.has(room.roomId)}>{children}</IsDirectRoomProvider>
|
||||||
|
</RoomProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!getAllParents(roomToParents, room.roomId).has(space.roomId)) {
|
||||||
|
if (getSpaceChildren(space).includes(room.roomId)) {
|
||||||
|
// fill missing roomToParent mapping
|
||||||
|
setRoomToParents({
|
||||||
|
type: 'PUT',
|
||||||
|
parent: space.roomId,
|
||||||
|
children: [room.roomId],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<JoinBeforeNavigate
|
<JoinBeforeNavigate
|
||||||
roomIdOrAlias={roomIdOrAlias!}
|
roomIdOrAlias={roomIdOrAlias!}
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,7 @@ import {
|
||||||
useRoomsNotificationPreferencesContext,
|
useRoomsNotificationPreferencesContext,
|
||||||
} from '../../../hooks/useRoomsNotificationPreferences';
|
} from '../../../hooks/useRoomsNotificationPreferences';
|
||||||
import { useOpenSpaceSettings } from '../../../state/hooks/spaceSettings';
|
import { useOpenSpaceSettings } from '../../../state/hooks/spaceSettings';
|
||||||
|
import { useRoomNavigate } from '../../../hooks/useRoomNavigate';
|
||||||
|
|
||||||
type SpaceMenuProps = {
|
type SpaceMenuProps = {
|
||||||
room: Room;
|
room: Room;
|
||||||
|
|
@ -83,11 +84,13 @@ type SpaceMenuProps = {
|
||||||
const SpaceMenu = forwardRef<HTMLDivElement, SpaceMenuProps>(({ room, requestClose }, ref) => {
|
const SpaceMenu = forwardRef<HTMLDivElement, SpaceMenuProps>(({ room, requestClose }, ref) => {
|
||||||
const mx = useMatrixClient();
|
const mx = useMatrixClient();
|
||||||
const [hideActivity] = useSetting(settingsAtom, 'hideActivity');
|
const [hideActivity] = useSetting(settingsAtom, 'hideActivity');
|
||||||
|
const [developerTools] = useSetting(settingsAtom, 'developerTools');
|
||||||
const roomToParents = useAtomValue(roomToParentsAtom);
|
const roomToParents = useAtomValue(roomToParentsAtom);
|
||||||
const powerLevels = usePowerLevels(room);
|
const powerLevels = usePowerLevels(room);
|
||||||
const { getPowerLevel, canDoAction } = usePowerLevelsAPI(powerLevels);
|
const { getPowerLevel, canDoAction } = usePowerLevelsAPI(powerLevels);
|
||||||
const canInvite = canDoAction('invite', getPowerLevel(mx.getUserId() ?? ''));
|
const canInvite = canDoAction('invite', getPowerLevel(mx.getUserId() ?? ''));
|
||||||
const openSpaceSettings = useOpenSpaceSettings();
|
const openSpaceSettings = useOpenSpaceSettings();
|
||||||
|
const { navigateRoom } = useRoomNavigate();
|
||||||
|
|
||||||
const allChild = useSpaceChildren(
|
const allChild = useSpaceChildren(
|
||||||
allRoomsAtom,
|
allRoomsAtom,
|
||||||
|
|
@ -118,6 +121,11 @@ const SpaceMenu = forwardRef<HTMLDivElement, SpaceMenuProps>(({ room, requestClo
|
||||||
requestClose();
|
requestClose();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleOpenTimeline = () => {
|
||||||
|
navigateRoom(room.roomId);
|
||||||
|
requestClose();
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Menu ref={ref} style={{ maxWidth: toRem(160), width: '100vw' }}>
|
<Menu ref={ref} style={{ maxWidth: toRem(160), width: '100vw' }}>
|
||||||
<Box direction="Column" gap="100" style={{ padding: config.space.S100 }}>
|
<Box direction="Column" gap="100" style={{ padding: config.space.S100 }}>
|
||||||
|
|
@ -168,6 +176,18 @@ const SpaceMenu = forwardRef<HTMLDivElement, SpaceMenuProps>(({ room, requestClo
|
||||||
Space Settings
|
Space Settings
|
||||||
</Text>
|
</Text>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
{developerTools && (
|
||||||
|
<MenuItem
|
||||||
|
onClick={handleOpenTimeline}
|
||||||
|
size="300"
|
||||||
|
after={<Icon size="100" src={Icons.Terminal} />}
|
||||||
|
radii="300"
|
||||||
|
>
|
||||||
|
<Text style={{ flexGrow: 1 }} as="span" size="T300" truncate>
|
||||||
|
Event Timeline
|
||||||
|
</Text>
|
||||||
|
</MenuItem>
|
||||||
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
<Line variant="Surface" size="300" />
|
<Line variant="Surface" size="300" />
|
||||||
<Box direction="Column" gap="100" style={{ padding: config.space.S100 }}>
|
<Box direction="Column" gap="100" style={{ padding: config.space.S100 }}>
|
||||||
|
|
|
||||||
|
|
@ -2,18 +2,307 @@ import React, { MutableRefObject, ReactNode, useEffect, useRef } from 'react';
|
||||||
|
|
||||||
import Prism from 'prismjs';
|
import Prism from 'prismjs';
|
||||||
|
|
||||||
import 'prismjs/components/prism-json';
|
import 'prismjs/components/prism-abap.js';
|
||||||
import 'prismjs/components/prism-javascript';
|
import 'prismjs/components/prism-abnf.js';
|
||||||
import 'prismjs/components/prism-typescript';
|
import 'prismjs/components/prism-actionscript.js';
|
||||||
import 'prismjs/components/prism-css';
|
import 'prismjs/components/prism-ada.js';
|
||||||
import 'prismjs/components/prism-sass';
|
import 'prismjs/components/prism-agda.js';
|
||||||
import 'prismjs/components/prism-swift';
|
import 'prismjs/components/prism-al.js';
|
||||||
import 'prismjs/components/prism-rust';
|
import 'prismjs/components/prism-antlr4.js';
|
||||||
import 'prismjs/components/prism-go';
|
import 'prismjs/components/prism-apacheconf.js';
|
||||||
import 'prismjs/components/prism-c';
|
import 'prismjs/components/prism-apex.js';
|
||||||
import 'prismjs/components/prism-cpp';
|
import 'prismjs/components/prism-apl.js';
|
||||||
import 'prismjs/components/prism-java';
|
import 'prismjs/components/prism-applescript.js';
|
||||||
import 'prismjs/components/prism-python';
|
import 'prismjs/components/prism-aql.js';
|
||||||
|
import 'prismjs/components/prism-arff.js';
|
||||||
|
import 'prismjs/components/prism-armasm.js';
|
||||||
|
import 'prismjs/components/prism-arturo.js';
|
||||||
|
import 'prismjs/components/prism-asciidoc.js';
|
||||||
|
import 'prismjs/components/prism-asm6502.js';
|
||||||
|
import 'prismjs/components/prism-asmatmel.js';
|
||||||
|
import 'prismjs/components/prism-aspnet.js';
|
||||||
|
import 'prismjs/components/prism-autohotkey.js';
|
||||||
|
import 'prismjs/components/prism-autoit.js';
|
||||||
|
import 'prismjs/components/prism-avisynth.js';
|
||||||
|
import 'prismjs/components/prism-avro-idl.js';
|
||||||
|
import 'prismjs/components/prism-awk.js';
|
||||||
|
import 'prismjs/components/prism-bash.js';
|
||||||
|
import 'prismjs/components/prism-basic.js';
|
||||||
|
import 'prismjs/components/prism-batch.js';
|
||||||
|
import 'prismjs/components/prism-bbcode.js';
|
||||||
|
import 'prismjs/components/prism-bbj.js';
|
||||||
|
import 'prismjs/components/prism-bicep.js';
|
||||||
|
import 'prismjs/components/prism-birb.js';
|
||||||
|
import 'prismjs/components/prism-bnf.js';
|
||||||
|
import 'prismjs/components/prism-bqn.js';
|
||||||
|
import 'prismjs/components/prism-brainfuck.js';
|
||||||
|
import 'prismjs/components/prism-brightscript.js';
|
||||||
|
import 'prismjs/components/prism-bro.js';
|
||||||
|
import 'prismjs/components/prism-bsl.js';
|
||||||
|
import 'prismjs/components/prism-c.js';
|
||||||
|
import 'prismjs/components/prism-cfscript.js';
|
||||||
|
import 'prismjs/components/prism-cil.js';
|
||||||
|
import 'prismjs/components/prism-cilkc.js';
|
||||||
|
import 'prismjs/components/prism-cilkcpp.js';
|
||||||
|
import 'prismjs/components/prism-clike.js';
|
||||||
|
import 'prismjs/components/prism-clojure.js';
|
||||||
|
import 'prismjs/components/prism-cmake.js';
|
||||||
|
import 'prismjs/components/prism-cobol.js';
|
||||||
|
import 'prismjs/components/prism-coffeescript.js';
|
||||||
|
import 'prismjs/components/prism-concurnas.js';
|
||||||
|
import 'prismjs/components/prism-cooklang.js';
|
||||||
|
import 'prismjs/components/prism-coq.js';
|
||||||
|
import 'prismjs/components/prism-cpp.js';
|
||||||
|
import 'prismjs/components/prism-csharp.js';
|
||||||
|
import 'prismjs/components/prism-cshtml.js';
|
||||||
|
import 'prismjs/components/prism-csp.js';
|
||||||
|
import 'prismjs/components/prism-css-extras.js';
|
||||||
|
import 'prismjs/components/prism-css.js';
|
||||||
|
import 'prismjs/components/prism-csv.js';
|
||||||
|
import 'prismjs/components/prism-cue.js';
|
||||||
|
import 'prismjs/components/prism-cypher.js';
|
||||||
|
import 'prismjs/components/prism-d.js';
|
||||||
|
import 'prismjs/components/prism-dart.js';
|
||||||
|
import 'prismjs/components/prism-dataweave.js';
|
||||||
|
import 'prismjs/components/prism-dax.js';
|
||||||
|
import 'prismjs/components/prism-dhall.js';
|
||||||
|
import 'prismjs/components/prism-diff.js';
|
||||||
|
import 'prismjs/components/prism-dns-zone-file.js';
|
||||||
|
import 'prismjs/components/prism-docker.js';
|
||||||
|
import 'prismjs/components/prism-dot.js';
|
||||||
|
import 'prismjs/components/prism-ebnf.js';
|
||||||
|
import 'prismjs/components/prism-editorconfig.js';
|
||||||
|
import 'prismjs/components/prism-eiffel.js';
|
||||||
|
import 'prismjs/components/prism-ejs.js';
|
||||||
|
import 'prismjs/components/prism-elixir.js';
|
||||||
|
import 'prismjs/components/prism-elm.js';
|
||||||
|
import 'prismjs/components/prism-erb.js';
|
||||||
|
import 'prismjs/components/prism-erlang.js';
|
||||||
|
import 'prismjs/components/prism-etlua.js';
|
||||||
|
import 'prismjs/components/prism-excel-formula.js';
|
||||||
|
import 'prismjs/components/prism-factor.js';
|
||||||
|
import 'prismjs/components/prism-false.js';
|
||||||
|
import 'prismjs/components/prism-firestore-security-rules.js';
|
||||||
|
import 'prismjs/components/prism-flow.js';
|
||||||
|
import 'prismjs/components/prism-fortran.js';
|
||||||
|
import 'prismjs/components/prism-fsharp.js';
|
||||||
|
import 'prismjs/components/prism-ftl.js';
|
||||||
|
import 'prismjs/components/prism-gap.js';
|
||||||
|
import 'prismjs/components/prism-gcode.js';
|
||||||
|
import 'prismjs/components/prism-gdscript.js';
|
||||||
|
import 'prismjs/components/prism-gedcom.js';
|
||||||
|
import 'prismjs/components/prism-gettext.js';
|
||||||
|
import 'prismjs/components/prism-gherkin.js';
|
||||||
|
import 'prismjs/components/prism-git.js';
|
||||||
|
import 'prismjs/components/prism-glsl.js';
|
||||||
|
import 'prismjs/components/prism-gml.js';
|
||||||
|
import 'prismjs/components/prism-gn.js';
|
||||||
|
import 'prismjs/components/prism-go-module.js';
|
||||||
|
import 'prismjs/components/prism-go.js';
|
||||||
|
import 'prismjs/components/prism-gradle.js';
|
||||||
|
import 'prismjs/components/prism-graphql.js';
|
||||||
|
import 'prismjs/components/prism-groovy.js';
|
||||||
|
import 'prismjs/components/prism-haml.js';
|
||||||
|
import 'prismjs/components/prism-handlebars.js';
|
||||||
|
import 'prismjs/components/prism-haskell.js';
|
||||||
|
import 'prismjs/components/prism-haxe.js';
|
||||||
|
import 'prismjs/components/prism-hcl.js';
|
||||||
|
import 'prismjs/components/prism-hlsl.js';
|
||||||
|
import 'prismjs/components/prism-hoon.js';
|
||||||
|
import 'prismjs/components/prism-hpkp.js';
|
||||||
|
import 'prismjs/components/prism-hsts.js';
|
||||||
|
import 'prismjs/components/prism-http.js';
|
||||||
|
import 'prismjs/components/prism-ichigojam.js';
|
||||||
|
import 'prismjs/components/prism-icon.js';
|
||||||
|
import 'prismjs/components/prism-icu-message-format.js';
|
||||||
|
import 'prismjs/components/prism-idris.js';
|
||||||
|
import 'prismjs/components/prism-iecst.js';
|
||||||
|
import 'prismjs/components/prism-ignore.js';
|
||||||
|
import 'prismjs/components/prism-inform7.js';
|
||||||
|
import 'prismjs/components/prism-ini.js';
|
||||||
|
import 'prismjs/components/prism-io.js';
|
||||||
|
import 'prismjs/components/prism-j.js';
|
||||||
|
import 'prismjs/components/prism-java.js';
|
||||||
|
import 'prismjs/components/prism-javadoclike.js';
|
||||||
|
import 'prismjs/components/prism-javascript.js';
|
||||||
|
import 'prismjs/components/prism-javastacktrace.js';
|
||||||
|
import 'prismjs/components/prism-jexl.js';
|
||||||
|
import 'prismjs/components/prism-jolie.js';
|
||||||
|
import 'prismjs/components/prism-jq.js';
|
||||||
|
import 'prismjs/components/prism-js-extras.js';
|
||||||
|
import 'prismjs/components/prism-js-templates.js';
|
||||||
|
import 'prismjs/components/prism-json.js';
|
||||||
|
import 'prismjs/components/prism-json5.js';
|
||||||
|
import 'prismjs/components/prism-jsonp.js';
|
||||||
|
import 'prismjs/components/prism-jsstacktrace.js';
|
||||||
|
import 'prismjs/components/prism-jsx.js';
|
||||||
|
import 'prismjs/components/prism-julia.js';
|
||||||
|
import 'prismjs/components/prism-keepalived.js';
|
||||||
|
import 'prismjs/components/prism-keyman.js';
|
||||||
|
import 'prismjs/components/prism-kotlin.js';
|
||||||
|
import 'prismjs/components/prism-kumir.js';
|
||||||
|
import 'prismjs/components/prism-kusto.js';
|
||||||
|
import 'prismjs/components/prism-latex.js';
|
||||||
|
import 'prismjs/components/prism-latte.js';
|
||||||
|
import 'prismjs/components/prism-less.js';
|
||||||
|
import 'prismjs/components/prism-lilypond.js';
|
||||||
|
import 'prismjs/components/prism-linker-script.js';
|
||||||
|
import 'prismjs/components/prism-liquid.js';
|
||||||
|
import 'prismjs/components/prism-lisp.js';
|
||||||
|
import 'prismjs/components/prism-livescript.js';
|
||||||
|
import 'prismjs/components/prism-llvm.js';
|
||||||
|
import 'prismjs/components/prism-log.js';
|
||||||
|
import 'prismjs/components/prism-lolcode.js';
|
||||||
|
import 'prismjs/components/prism-lua.js';
|
||||||
|
import 'prismjs/components/prism-magma.js';
|
||||||
|
import 'prismjs/components/prism-makefile.js';
|
||||||
|
import 'prismjs/components/prism-markdown.js';
|
||||||
|
import 'prismjs/components/prism-markup-templating.js';
|
||||||
|
import 'prismjs/components/prism-markup.js';
|
||||||
|
import 'prismjs/components/prism-mata.js';
|
||||||
|
import 'prismjs/components/prism-matlab.js';
|
||||||
|
import 'prismjs/components/prism-maxscript.js';
|
||||||
|
import 'prismjs/components/prism-mel.js';
|
||||||
|
import 'prismjs/components/prism-mermaid.js';
|
||||||
|
import 'prismjs/components/prism-metafont.js';
|
||||||
|
import 'prismjs/components/prism-mizar.js';
|
||||||
|
import 'prismjs/components/prism-mongodb.js';
|
||||||
|
import 'prismjs/components/prism-monkey.js';
|
||||||
|
import 'prismjs/components/prism-moonscript.js';
|
||||||
|
import 'prismjs/components/prism-n1ql.js';
|
||||||
|
import 'prismjs/components/prism-n4js.js';
|
||||||
|
import 'prismjs/components/prism-nand2tetris-hdl.js';
|
||||||
|
import 'prismjs/components/prism-naniscript.js';
|
||||||
|
import 'prismjs/components/prism-nasm.js';
|
||||||
|
import 'prismjs/components/prism-neon.js';
|
||||||
|
import 'prismjs/components/prism-nevod.js';
|
||||||
|
import 'prismjs/components/prism-nginx.js';
|
||||||
|
import 'prismjs/components/prism-nim.js';
|
||||||
|
import 'prismjs/components/prism-nix.js';
|
||||||
|
import 'prismjs/components/prism-nsis.js';
|
||||||
|
import 'prismjs/components/prism-objectivec.js';
|
||||||
|
import 'prismjs/components/prism-ocaml.js';
|
||||||
|
import 'prismjs/components/prism-odin.js';
|
||||||
|
import 'prismjs/components/prism-opencl.js';
|
||||||
|
import 'prismjs/components/prism-openqasm.js';
|
||||||
|
import 'prismjs/components/prism-oz.js';
|
||||||
|
import 'prismjs/components/prism-parigp.js';
|
||||||
|
import 'prismjs/components/prism-parser.js';
|
||||||
|
import 'prismjs/components/prism-pascal.js';
|
||||||
|
import 'prismjs/components/prism-pascaligo.js';
|
||||||
|
import 'prismjs/components/prism-pcaxis.js';
|
||||||
|
import 'prismjs/components/prism-peoplecode.js';
|
||||||
|
import 'prismjs/components/prism-perl.js';
|
||||||
|
import 'prismjs/components/prism-php-extras.js';
|
||||||
|
import 'prismjs/components/prism-php.js';
|
||||||
|
import 'prismjs/components/prism-phpdoc.js';
|
||||||
|
import 'prismjs/components/prism-plant-uml.js';
|
||||||
|
import 'prismjs/components/prism-powerquery.js';
|
||||||
|
import 'prismjs/components/prism-powershell.js';
|
||||||
|
import 'prismjs/components/prism-processing.js';
|
||||||
|
import 'prismjs/components/prism-prolog.js';
|
||||||
|
import 'prismjs/components/prism-promql.js';
|
||||||
|
import 'prismjs/components/prism-properties.js';
|
||||||
|
import 'prismjs/components/prism-protobuf.js';
|
||||||
|
import 'prismjs/components/prism-psl.js';
|
||||||
|
import 'prismjs/components/prism-pug.js';
|
||||||
|
import 'prismjs/components/prism-puppet.js';
|
||||||
|
import 'prismjs/components/prism-pure.js';
|
||||||
|
import 'prismjs/components/prism-purebasic.js';
|
||||||
|
import 'prismjs/components/prism-purescript.js';
|
||||||
|
import 'prismjs/components/prism-python.js';
|
||||||
|
import 'prismjs/components/prism-q.js';
|
||||||
|
import 'prismjs/components/prism-qml.js';
|
||||||
|
import 'prismjs/components/prism-qore.js';
|
||||||
|
import 'prismjs/components/prism-qsharp.js';
|
||||||
|
import 'prismjs/components/prism-r.js';
|
||||||
|
import 'prismjs/components/prism-reason.js';
|
||||||
|
import 'prismjs/components/prism-regex.js';
|
||||||
|
import 'prismjs/components/prism-rego.js';
|
||||||
|
import 'prismjs/components/prism-renpy.js';
|
||||||
|
import 'prismjs/components/prism-rescript.js';
|
||||||
|
import 'prismjs/components/prism-rest.js';
|
||||||
|
import 'prismjs/components/prism-rip.js';
|
||||||
|
import 'prismjs/components/prism-roboconf.js';
|
||||||
|
import 'prismjs/components/prism-robotframework.js';
|
||||||
|
import 'prismjs/components/prism-ruby.js';
|
||||||
|
import 'prismjs/components/prism-rust.js';
|
||||||
|
import 'prismjs/components/prism-sas.js';
|
||||||
|
import 'prismjs/components/prism-sass.js';
|
||||||
|
import 'prismjs/components/prism-scala.js';
|
||||||
|
import 'prismjs/components/prism-scheme.js';
|
||||||
|
import 'prismjs/components/prism-scss.js';
|
||||||
|
import 'prismjs/components/prism-shell-session.js';
|
||||||
|
import 'prismjs/components/prism-smali.js';
|
||||||
|
import 'prismjs/components/prism-smalltalk.js';
|
||||||
|
import 'prismjs/components/prism-smarty.js';
|
||||||
|
import 'prismjs/components/prism-sml.js';
|
||||||
|
import 'prismjs/components/prism-solidity.js';
|
||||||
|
import 'prismjs/components/prism-solution-file.js';
|
||||||
|
import 'prismjs/components/prism-soy.js';
|
||||||
|
import 'prismjs/components/prism-splunk-spl.js';
|
||||||
|
import 'prismjs/components/prism-sqf.js';
|
||||||
|
import 'prismjs/components/prism-sql.js';
|
||||||
|
import 'prismjs/components/prism-squirrel.js';
|
||||||
|
import 'prismjs/components/prism-stan.js';
|
||||||
|
import 'prismjs/components/prism-stata.js';
|
||||||
|
import 'prismjs/components/prism-stylus.js';
|
||||||
|
import 'prismjs/components/prism-supercollider.js';
|
||||||
|
import 'prismjs/components/prism-swift.js';
|
||||||
|
import 'prismjs/components/prism-systemd.js';
|
||||||
|
import 'prismjs/components/prism-t4-templating.js';
|
||||||
|
import 'prismjs/components/prism-t4-vb.js';
|
||||||
|
import 'prismjs/components/prism-tap.js';
|
||||||
|
import 'prismjs/components/prism-tcl.js';
|
||||||
|
import 'prismjs/components/prism-textile.js';
|
||||||
|
import 'prismjs/components/prism-toml.js';
|
||||||
|
import 'prismjs/components/prism-tremor.js';
|
||||||
|
import 'prismjs/components/prism-tsx.js';
|
||||||
|
import 'prismjs/components/prism-tt2.js';
|
||||||
|
import 'prismjs/components/prism-turtle.js';
|
||||||
|
import 'prismjs/components/prism-twig.js';
|
||||||
|
import 'prismjs/components/prism-typescript.js';
|
||||||
|
import 'prismjs/components/prism-typoscript.js';
|
||||||
|
import 'prismjs/components/prism-unrealscript.js';
|
||||||
|
import 'prismjs/components/prism-uorazor.js';
|
||||||
|
import 'prismjs/components/prism-uri.js';
|
||||||
|
import 'prismjs/components/prism-v.js';
|
||||||
|
import 'prismjs/components/prism-vala.js';
|
||||||
|
import 'prismjs/components/prism-vbnet.js';
|
||||||
|
import 'prismjs/components/prism-velocity.js';
|
||||||
|
import 'prismjs/components/prism-verilog.js';
|
||||||
|
import 'prismjs/components/prism-vhdl.js';
|
||||||
|
import 'prismjs/components/prism-vim.js';
|
||||||
|
import 'prismjs/components/prism-visual-basic.js';
|
||||||
|
import 'prismjs/components/prism-warpscript.js';
|
||||||
|
import 'prismjs/components/prism-wasm.js';
|
||||||
|
import 'prismjs/components/prism-web-idl.js';
|
||||||
|
import 'prismjs/components/prism-wgsl.js';
|
||||||
|
import 'prismjs/components/prism-wiki.js';
|
||||||
|
import 'prismjs/components/prism-wolfram.js';
|
||||||
|
import 'prismjs/components/prism-wren.js';
|
||||||
|
import 'prismjs/components/prism-xeora.js';
|
||||||
|
import 'prismjs/components/prism-xml-doc.js';
|
||||||
|
import 'prismjs/components/prism-xojo.js';
|
||||||
|
import 'prismjs/components/prism-xquery.js';
|
||||||
|
import 'prismjs/components/prism-yaml.js';
|
||||||
|
import 'prismjs/components/prism-yang.js';
|
||||||
|
import 'prismjs/components/prism-zig.js';
|
||||||
|
import 'prismjs/components/prism-arduino.js';
|
||||||
|
|
||||||
|
// Broken:
|
||||||
|
//
|
||||||
|
// import 'prismjs/components/prism-bison.js';
|
||||||
|
// import 'prismjs/components/prism-chaiscript.js';
|
||||||
|
// import 'prismjs/components/prism-core.js';
|
||||||
|
// import 'prismjs/components/prism-crystal.js';
|
||||||
|
// import 'prismjs/components/prism-django.js';
|
||||||
|
// import 'prismjs/components/prism-javadoc.js';
|
||||||
|
// import 'prismjs/components/prism-jsdoc.js';
|
||||||
|
// import 'prismjs/components/prism-plsql.js';
|
||||||
|
// import 'prismjs/components/prism-racket.js';
|
||||||
|
// import 'prismjs/components/prism-sparql.js';
|
||||||
|
// import 'prismjs/components/prism-t4-cs.js';
|
||||||
|
|
||||||
import './ReactPrism.css';
|
import './ReactPrism.css';
|
||||||
// using classNames .prism-dark .prism-light from ReactPrism.css
|
// using classNames .prism-dark .prism-light from ReactPrism.css
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ import {
|
||||||
|
|
||||||
const NAV_TO_ACTIVE_PATH = 'navToActivePath';
|
const NAV_TO_ACTIVE_PATH = 'navToActivePath';
|
||||||
|
|
||||||
|
const getStoreKey = (userId: string): string => `${NAV_TO_ACTIVE_PATH}${userId}`;
|
||||||
|
|
||||||
type NavToActivePath = Map<string, Path>;
|
type NavToActivePath = Map<string, Path>;
|
||||||
|
|
||||||
type NavToActivePathAction =
|
type NavToActivePathAction =
|
||||||
|
|
@ -25,7 +27,7 @@ type NavToActivePathAction =
|
||||||
export type NavToActivePathAtom = WritableAtom<NavToActivePath, [NavToActivePathAction], undefined>;
|
export type NavToActivePathAtom = WritableAtom<NavToActivePath, [NavToActivePathAction], undefined>;
|
||||||
|
|
||||||
export const makeNavToActivePathAtom = (userId: string): NavToActivePathAtom => {
|
export const makeNavToActivePathAtom = (userId: string): NavToActivePathAtom => {
|
||||||
const storeKey = `${NAV_TO_ACTIVE_PATH}${userId}`;
|
const storeKey = getStoreKey(userId);
|
||||||
|
|
||||||
const baseNavToActivePathAtom = atomWithLocalStorage<NavToActivePath>(
|
const baseNavToActivePathAtom = atomWithLocalStorage<NavToActivePath>(
|
||||||
storeKey,
|
storeKey,
|
||||||
|
|
@ -64,3 +66,7 @@ export const makeNavToActivePathAtom = (userId: string): NavToActivePathAtom =>
|
||||||
|
|
||||||
return navToActivePathAtom;
|
return navToActivePathAtom;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const clearNavToActivePathStore = (userId: string) => {
|
||||||
|
localStorage.removeItem(getStoreKey(userId));
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { createClient, MatrixClient, IndexedDBStore, IndexedDBCryptoStore } from 'matrix-js-sdk';
|
import { createClient, MatrixClient, IndexedDBStore, IndexedDBCryptoStore } from 'matrix-js-sdk';
|
||||||
|
|
||||||
import { cryptoCallbacks } from './state/secretStorageKeys';
|
import { cryptoCallbacks } from './state/secretStorageKeys';
|
||||||
|
import { clearNavToActivePathStore } from '../app/state/navToActivePath';
|
||||||
|
|
||||||
type Session = {
|
type Session = {
|
||||||
baseUrl: string;
|
baseUrl: string;
|
||||||
|
|
@ -46,6 +47,7 @@ export const startClient = async (mx: MatrixClient) => {
|
||||||
|
|
||||||
export const clearCacheAndReload = async (mx: MatrixClient) => {
|
export const clearCacheAndReload = async (mx: MatrixClient) => {
|
||||||
mx.stopClient();
|
mx.stopClient();
|
||||||
|
clearNavToActivePathStore(mx.getSafeUserId());
|
||||||
await mx.store.deleteAllData();
|
await mx.store.deleteAllData();
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
const cons = {
|
const cons = {
|
||||||
version: '4.8.0',
|
version: '4.8.1',
|
||||||
secretKey: {
|
secretKey: {
|
||||||
ACCESS_TOKEN: 'cinny_access_token',
|
ACCESS_TOKEN: 'cinny_access_token',
|
||||||
DEVICE_ID: 'cinny_device_id',
|
DEVICE_ID: 'cinny_device_id',
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue