From f7e1626e6929b8f966066020a3668c0d50b2605a Mon Sep 17 00:00:00 2001 From: Matthew Horan Date: Thu, 14 Nov 2024 18:26:28 -0500 Subject: [PATCH] Update line on _buffer_line_data_changed When a line is changed (e.g. the message is edited), WeeChat now sends a _buffer_line_data_changed message. Update line state so that line changes are reflected in WeechatRN. Upgrade to Node v22 for toSpliced support. --- .github/workflows/check.yml | 2 +- .github/workflows/publish.yml | 2 +- __tests__/lib/weechat/action_transformer.ts | 41 +++++++++++++++++++++ src/lib/weechat/action_transformer.ts | 27 +++++++++++--- src/store/actions.ts | 4 ++ src/store/lines.ts | 13 +++++++ 6 files changed, 82 insertions(+), 7 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 2a523e0..bb786d4 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -15,7 +15,7 @@ jobs: - name: Set up Node and cache dependencies uses: actions/setup-node@v4 with: - node-version: 18 + node-version: 22 cache: npm - run: npm install - run: npm test -- --testTimeout 10000 diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index a02678a..5d1f182 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -14,7 +14,7 @@ jobs: - name: Set up Node uses: actions/setup-node@v4 with: - node-version: 18 + node-version: 22 cache: npm - name: Set up Expo uses: expo/expo-github-action@v8 diff --git a/__tests__/lib/weechat/action_transformer.ts b/__tests__/lib/weechat/action_transformer.ts index f2edb0f..54d1506 100644 --- a/__tests__/lib/weechat/action_transformer.ts +++ b/__tests__/lib/weechat/action_transformer.ts @@ -563,6 +563,47 @@ describe('transformToReduxAction', () => { }); }); + describe('on buffer_line_data_changed', () => { + it('updates the line', () => { + const preloadedState = { + lines: { '83d204d80': [{ id: 0 } as WeechatLine] } + }; + const store = configureStore({ + reducer, + preloadedState, + enhancers: (getDefaultEnhancers) => + getDefaultEnhancers({ autoBatch: false }) + }); + + const action = transformToReduxAction({ + id: '_buffer_line_data_changed', + header: { compression: 0, length: 0 }, + objects: [ + { + type: 'hda', + content: [ + { + id: 0, + buffer: '83d204d80', + pointers: ['83d204d80', '83c016280', '838a65900', '83c000420'], + date: new Date('2024-11-09T00:02:07.000Z'), + date_printed: new Date('2024-11-10T17:28:48.000Z'), + message: 'Beep boop' + } + ] + } + ] + }); + expect(action).toBeDefined(); + + store.dispatch(action!); + + expect(store.getState().lines).toHaveProperty('83d204d80'); + const lines = store.getState().lines['83d204d80']; + expect(lines[0].message).toEqual('Beep boop'); + }); + }); + describe('on version', () => { it('stores the version', () => { const store = configureStore({ diff --git a/src/lib/weechat/action_transformer.ts b/src/lib/weechat/action_transformer.ts index 8c98c2a..b9cdf53 100644 --- a/src/lib/weechat/action_transformer.ts +++ b/src/lib/weechat/action_transformer.ts @@ -1,9 +1,11 @@ +import { UnknownAction } from 'redux'; import { ThunkAction, ThunkDispatch } from 'redux-thunk'; import { StoreState } from '../../store'; import { bufferClearedAction, bufferClosedAction, bufferLineAddedAction, + bufferLineDataChangedAction, bufferLocalvarRemoveAction, bufferLocalvarUpdateAction, bufferOpenedAction, @@ -13,14 +15,13 @@ import { fetchHotlistsAction, fetchLinesAction, fetchNicklistAction, + fetchScriptsAction, fetchVersionAction, lastReadLinesAction, nicklistUpdatedAction, - fetchScriptsAction, - upgradeAction, - pongAction + pongAction, + upgradeAction } from '../../store/actions'; -import { UnknownAction } from 'redux'; type KeyFn = (t: T) => string; type MapFn = (a: A) => A | B; @@ -32,7 +33,7 @@ const reduceToObjectByKey = ( ) => array.reduce((acc, elem) => ({ ...acc, [keyFn(elem)]: mapFn(elem) }), {}); const parseVersion = (version: string) => { - const parts = version.split('.').map((part) => parseInt(part) || 0); + const parts = version.split('.').map((part) => parseInt(part) ?? 0); return (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8) | parts[3]; }; @@ -112,6 +113,22 @@ export const transformToReduxAction = ( ); }; } + case '_buffer_line_data_changed': { + const object = data.objects[0] as WeechatObject< + Record[] + >; + const line = object.content[0]; + const { id, date, date_printed, ...restLine } = line; + + if (id === undefined) return; + + return bufferLineDataChangedAction({ + ...restLine, + id, + date: (date as Date).toISOString(), + date_printed: (date_printed as Date).toISOString() + } as WeechatLine); + } case '_buffer_closing': { const object = data.objects[0] as WeechatObject; const buffer = object.content[0]; diff --git a/src/store/actions.ts b/src/store/actions.ts index 20cb651..2272178 100644 --- a/src/store/actions.ts +++ b/src/store/actions.ts @@ -88,6 +88,10 @@ export const bufferLineAddedAction = createAction( 'BUFFER_LINE_ADDED', prepareAutoBatched<{ line: WeechatLine; currentBufferId: string | null }>() ); +export const bufferLineDataChangedAction = createAction( + 'BUFFER_LINE_DATA_CHANGED', + prepareAutoBatched() +); export const bufferClearedAction = createAction( 'BUFFER_CLEARED', prepareAutoBatched() diff --git a/src/store/lines.ts b/src/store/lines.ts index 496bf1d..042df99 100644 --- a/src/store/lines.ts +++ b/src/store/lines.ts @@ -3,6 +3,7 @@ import { bufferClearedAction, bufferClosedAction, bufferLineAddedAction, + bufferLineDataChangedAction, fetchBuffersRemovedAction, fetchLinesAction, upgradeAction @@ -38,6 +39,18 @@ const linesReducer = createReducer(initialState, (builder) => { ] }; }); + builder.addCase(bufferLineDataChangedAction, (state, action) => { + const lines = state[action.payload.buffer]; + if (lines === undefined) return state; + + const lineIndex = lines.findIndex((line) => line.id === action.payload.id); + if (lineIndex < 0) return state; + + return { + ...state, + [action.payload.buffer]: lines.toSpliced(lineIndex, 1, action.payload) + }; + }); builder.addCase(fetchBuffersRemovedAction, (state, action) => { return Object.fromEntries( Object.entries(state).filter(