mirror of
https://github.com/cinnyapp/cinny.git
synced 2025-11-17 04:30:29 +03:00
Add sliding sync support and change font to SF Pro Display
- Enable sliding sync in config.json with matrix.org proxy - Update font from InterVariable to SF Pro Display - Add sliding sync state management with Jotai atoms - Create bridge between sliding sync and existing room list atoms - Add sliding sync settings UI in General settings - Implement purple theme with gradient enhancements - Add synchronization status display for sliding sync - Update client initialization to support sliding sync 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
67b05eeb09
commit
d25cc7250b
25 changed files with 1510 additions and 14 deletions
|
|
@ -5,13 +5,28 @@ import { mDirectAtom, useBindMDirectAtom } from '../mDirectList';
|
|||
import { roomToUnreadAtom, useBindRoomToUnreadAtom } from '../room/roomToUnread';
|
||||
import { roomToParentsAtom, useBindRoomToParentsAtom } from '../room/roomToParents';
|
||||
import { roomIdToTypingMembersAtom, useBindRoomIdToTypingMembersAtom } from '../typingMembers';
|
||||
import { useBindSlidingSyncAtom, useSlidingSyncRoomListBridge, useShouldUseSlidingSync } from '../sliding-sync';
|
||||
import { getSlidingSync } from '../../../client/initMatrix';
|
||||
|
||||
export const useBindAtoms = (mx: MatrixClient) => {
|
||||
const slidingSync = getSlidingSync();
|
||||
const shouldUseSlidingSync = useShouldUseSlidingSync();
|
||||
|
||||
// Bind sliding sync atoms if enabled
|
||||
useBindSlidingSyncAtom(mx, slidingSync);
|
||||
|
||||
// Bridge sliding sync data to existing room list atoms
|
||||
useSlidingSyncRoomListBridge();
|
||||
|
||||
// Only bind traditional room list atoms if not using sliding sync
|
||||
if (!shouldUseSlidingSync) {
|
||||
useBindAllInvitesAtom(mx, allInvitesAtom);
|
||||
useBindAllRoomsAtom(mx, allRoomsAtom);
|
||||
}
|
||||
|
||||
// These atoms are always bound regardless of sync method
|
||||
useBindMDirectAtom(mx, mDirectAtom);
|
||||
useBindAllInvitesAtom(mx, allInvitesAtom);
|
||||
useBindAllRoomsAtom(mx, allRoomsAtom);
|
||||
useBindRoomToParentsAtom(mx, roomToParentsAtom);
|
||||
useBindRoomToUnreadAtom(mx, roomToUnreadAtom);
|
||||
|
||||
useBindRoomIdToTypingMembersAtom(mx, roomIdToTypingMembersAtom);
|
||||
};
|
||||
|
|
|
|||
3
src/app/state/sliding-sync/index.ts
Normal file
3
src/app/state/sliding-sync/index.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export * from './slidingSync';
|
||||
export * from './useSlidingSync';
|
||||
export * from './roomListBridge';
|
||||
40
src/app/state/sliding-sync/roomListBridge.ts
Normal file
40
src/app/state/sliding-sync/roomListBridge.ts
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
import { useSetAtom, useAtomValue } from 'jotai';
|
||||
import { useEffect } from 'react';
|
||||
import { allRoomsAtom } from '../room-list/roomList';
|
||||
import { allInvitesAtom } from '../room-list/inviteList';
|
||||
import { slidingSyncRoomListAtom, slidingSyncEnabledAtom } from './slidingSync';
|
||||
|
||||
/**
|
||||
* Bridge sliding sync room list data to existing Cinny room list atoms
|
||||
* This allows existing UI components to work seamlessly with sliding sync
|
||||
*/
|
||||
export const useSlidingSyncRoomListBridge = () => {
|
||||
const slidingSyncEnabled = useAtomValue(slidingSyncEnabledAtom);
|
||||
const slidingSyncRoomList = useAtomValue(slidingSyncRoomListAtom);
|
||||
const setAllRooms = useSetAtom(allRoomsAtom);
|
||||
const setAllInvites = useSetAtom(allInvitesAtom);
|
||||
|
||||
useEffect(() => {
|
||||
if (!slidingSyncEnabled) return;
|
||||
|
||||
// Bridge sliding sync room lists to existing atoms
|
||||
const allRoomsList = slidingSyncRoomList.allRooms || [];
|
||||
const directMessagesList = slidingSyncRoomList.directMessages || [];
|
||||
const invitesList = slidingSyncRoomList.invites || [];
|
||||
|
||||
// Combine all rooms and DMs for the all rooms atom
|
||||
const combinedRooms = [...allRoomsList, ...directMessagesList];
|
||||
|
||||
// Update existing atoms
|
||||
setAllRooms({ type: 'INITIALIZE', rooms: combinedRooms });
|
||||
setAllInvites({ type: 'INITIALIZE', invites: invitesList });
|
||||
|
||||
}, [slidingSyncEnabled, slidingSyncRoomList, setAllRooms, setAllInvites]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook to determine if sliding sync should override traditional sync behavior
|
||||
*/
|
||||
export const useShouldUseSlidingSync = () => {
|
||||
return useAtomValue(slidingSyncEnabledAtom);
|
||||
};
|
||||
20
src/app/state/sliding-sync/slidingSync.ts
Normal file
20
src/app/state/sliding-sync/slidingSync.ts
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import { atom } from 'jotai';
|
||||
import { SlidingSync } from 'matrix-js-sdk/lib/sliding-sync';
|
||||
|
||||
// Sliding sync instance atom
|
||||
export const slidingSyncAtom = atom<SlidingSync | null>(null);
|
||||
|
||||
// Sliding sync state atom
|
||||
export const slidingSyncStateAtom = atom<'PREPARED' | 'SYNCING' | 'STOPPED' | 'ERROR'>('STOPPED');
|
||||
|
||||
// Sliding sync enabled atom
|
||||
export const slidingSyncEnabledAtom = atom<boolean>(false);
|
||||
|
||||
// Room list data from sliding sync
|
||||
export const slidingSyncRoomListAtom = atom<Record<string, string[]>>({});
|
||||
|
||||
// Room data from sliding sync
|
||||
export const slidingSyncRoomDataAtom = atom<Record<string, any>>({});
|
||||
|
||||
// Error state for sliding sync
|
||||
export const slidingSyncErrorAtom = atom<Error | null>(null);
|
||||
79
src/app/state/sliding-sync/useSlidingSync.ts
Normal file
79
src/app/state/sliding-sync/useSlidingSync.ts
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
import { useSetAtom, useAtomValue } from 'jotai';
|
||||
import { useEffect } from 'react';
|
||||
import { MatrixClient } from 'matrix-js-sdk';
|
||||
import { SlidingSync, SlidingSyncEvent } from 'matrix-js-sdk/lib/sliding-sync';
|
||||
import {
|
||||
slidingSyncAtom,
|
||||
slidingSyncStateAtom,
|
||||
slidingSyncEnabledAtom,
|
||||
slidingSyncRoomListAtom,
|
||||
slidingSyncRoomDataAtom,
|
||||
slidingSyncErrorAtom
|
||||
} from './slidingSync';
|
||||
|
||||
export const useBindSlidingSyncAtom = (mx: MatrixClient, slidingSync: SlidingSync | null) => {
|
||||
const setSlidingSync = useSetAtom(slidingSyncAtom);
|
||||
const setSlidingSyncState = useSetAtom(slidingSyncStateAtom);
|
||||
const setSlidingSyncEnabled = useSetAtom(slidingSyncEnabledAtom);
|
||||
const setSlidingSyncRoomList = useSetAtom(slidingSyncRoomListAtom);
|
||||
const setSlidingSyncRoomData = useSetAtom(slidingSyncRoomDataAtom);
|
||||
const setSlidingSyncError = useSetAtom(slidingSyncErrorAtom);
|
||||
|
||||
useEffect(() => {
|
||||
if (!slidingSync) {
|
||||
setSlidingSyncEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
setSlidingSync(slidingSync);
|
||||
setSlidingSyncEnabled(true);
|
||||
|
||||
const handleSyncUpdate = () => {
|
||||
setSlidingSyncState('SYNCING');
|
||||
|
||||
// Extract room lists
|
||||
const lists: Record<string, string[]> = {};
|
||||
slidingSync.getListData().forEach((listData, listKey) => {
|
||||
lists[listKey] = listData.joinedRooms || [];
|
||||
});
|
||||
setSlidingSyncRoomList(lists);
|
||||
|
||||
// Extract room data
|
||||
const roomData: Record<string, any> = {};
|
||||
slidingSync.getRoomData().forEach((data, roomId) => {
|
||||
roomData[roomId] = data;
|
||||
});
|
||||
setSlidingSyncRoomData(roomData);
|
||||
};
|
||||
|
||||
const handleSyncComplete = () => {
|
||||
setSlidingSyncState('PREPARED');
|
||||
setSlidingSyncError(null);
|
||||
};
|
||||
|
||||
const handleSyncError = (error: Error) => {
|
||||
setSlidingSyncState('ERROR');
|
||||
setSlidingSyncError(error);
|
||||
};
|
||||
|
||||
// Bind sliding sync events
|
||||
slidingSync.on(SlidingSyncEvent.List, handleSyncUpdate);
|
||||
slidingSync.on(SlidingSyncEvent.RoomData, handleSyncUpdate);
|
||||
// Note: These event names might need adjustment based on actual SDK events
|
||||
slidingSync.on('sync' as any, handleSyncComplete);
|
||||
slidingSync.on('error' as any, handleSyncError);
|
||||
|
||||
return () => {
|
||||
slidingSync.removeListener(SlidingSyncEvent.List, handleSyncUpdate);
|
||||
slidingSync.removeListener(SlidingSyncEvent.RoomData, handleSyncUpdate);
|
||||
slidingSync.removeListener('sync' as any, handleSyncComplete);
|
||||
slidingSync.removeListener('error' as any, handleSyncError);
|
||||
};
|
||||
}, [mx, slidingSync, setSlidingSync, setSlidingSyncState, setSlidingSyncEnabled, setSlidingSyncRoomList, setSlidingSyncRoomData, setSlidingSyncError]);
|
||||
};
|
||||
|
||||
export const useSlidingSyncEnabled = () => useAtomValue(slidingSyncEnabledAtom);
|
||||
export const useSlidingSyncState = () => useAtomValue(slidingSyncStateAtom);
|
||||
export const useSlidingSyncRoomList = () => useAtomValue(slidingSyncRoomListAtom);
|
||||
export const useSlidingSyncRoomData = () => useAtomValue(slidingSyncRoomDataAtom);
|
||||
export const useSlidingSyncError = () => useAtomValue(slidingSyncErrorAtom);
|
||||
Loading…
Add table
Add a link
Reference in a new issue