action_transformer.ts (5130B)
1 import { StoreState } from '../../store'; 2 3 export type WeechatReduxAction = { 4 type: string; 5 payload: any; 6 }; 7 8 type KeyFn<T> = (t: T) => string; 9 type MapFn<A, B> = (a: A) => A | B; 10 11 const reduceToObjectByKey = <T, U>( 12 array: T[], 13 keyFn: KeyFn<T>, 14 mapFn: MapFn<T, U> = (a) => a 15 ) => array.reduce((acc, elem) => ({ ...acc, [keyFn(elem)]: mapFn(elem) }), {}); 16 17 export const transformToReduxAction = (data: WeechatResponse<any>) => { 18 switch (data.id) { 19 // Weechat internal events starts with "_" 20 case '_nicklist_diff': { 21 const object = data.objects[0] as WeechatObject<WeechatNicklist[]>; 22 const nicklistDiffs = object.content; 23 24 const nick = nicklistDiffs.filter((diff) => diff.group === 0)[0]; 25 26 if (nick) { 27 const bufferId = nick.pointers[0]; 28 const payload = nick; 29 30 switch (String.fromCharCode(nick._diff)) { 31 case '+': { 32 return { 33 type: 'NICK_ADDED', 34 bufferId, 35 payload 36 }; 37 } 38 case '-': { 39 return { 40 type: 'NICK_REMOVED', 41 bufferId, 42 payload 43 }; 44 } 45 case '*': { 46 return { 47 type: 'NICK_UPDATED', 48 bufferId, 49 payload 50 }; 51 } 52 } 53 } 54 55 return null; 56 } 57 case '_buffer_line_added': { 58 const object = data.objects[0] as WeechatObject<WeechatLine[]>; 59 const line = object.content[0]; 60 61 return (dispatch, getState) => { 62 const state: StoreState = getState(); 63 64 dispatch({ 65 type: 'BUFFER_LINE_ADDED', 66 bufferId: line.buffer, 67 currentBufferId: state.app.currentBufferId, 68 payload: line 69 }); 70 }; 71 } 72 case '_buffer_closing': { 73 const object = data.objects[0] as WeechatObject<WeechatBuffer[]>; 74 const buffer = object.content[0]; 75 76 return { 77 type: 'BUFFER_CLOSED', 78 bufferId: buffer.pointers[0] 79 }; 80 } 81 case '_buffer_opened': { 82 const object = data.objects[0] as WeechatObject<WeechatBuffer[]>; 83 const buffer = object.content[0]; 84 buffer.id = buffer.pointers[0]; 85 86 return { 87 type: 'BUFFER_OPENED', 88 payload: buffer, 89 bufferId: buffer.id 90 }; 91 } 92 case '_buffer_renamed': { 93 const object = data.objects[0] as WeechatObject<WeechatBuffer[]>; 94 const buffer = object.content[0]; 95 buffer.id = buffer.pointers[0]; 96 97 return { 98 type: 'BUFFER_RENAMED', 99 payload: buffer, 100 bufferId: buffer.id 101 }; 102 } 103 case '_buffer_localvar_removed': { 104 const object = data.objects[0] as WeechatObject<WeechatBuffer[]>; 105 const buffer = object.content[0]; 106 buffer.id = buffer.pointers[0]; 107 108 return { 109 type: 'BUFFER_LOCALVAR_REMOVE', 110 payload: buffer, 111 bufferId: buffer.id 112 }; 113 } 114 case '_buffer_title_changed': 115 case '_buffer_localvar_added': { 116 const object = data.objects[0] as WeechatObject<WeechatBuffer[]>; 117 const buffer = object.content[0]; 118 buffer.id = buffer.pointers[0]; 119 120 return { 121 type: 'BUFFER_LOCALVAR_UPDATE', 122 payload: buffer, 123 bufferId: buffer.id 124 }; 125 } 126 case 'hotlist': { 127 const object = data.objects[0] as WeechatObject<WeechatHotlist[]>; 128 129 return (dispatch, getState) => { 130 const state: StoreState = getState(); 131 132 dispatch({ 133 type: 'FETCH_HOTLISTS', 134 payload: reduceToObjectByKey( 135 object.content, 136 (hotlist) => hotlist.buffer, 137 (h) => { 138 const [, message, privmsg, highlight] = h.count; 139 const sum = message + privmsg + highlight; 140 return { ...h, message, privmsg, highlight, sum }; 141 } 142 ), 143 currentBufferId: state.app.currentBufferId 144 }); 145 }; 146 } 147 case 'nicklist': { 148 const object = data.objects[0] as WeechatObject<WeechatNicklist[]>; 149 const nicklistDiffs = object.content; 150 151 const nicks = nicklistDiffs.filter((diff) => diff.group === 0); 152 153 return { 154 type: 'FETCH_NICKLIST', 155 bufferId: object.content[0].pointers[0], 156 payload: nicks 157 }; 158 } 159 case 'buffers': { 160 const object = data.objects[0] as WeechatObject<WeechatBuffer[]>; 161 162 return { 163 type: 'FETCH_BUFFERS', 164 payload: reduceToObjectByKey( 165 object.content, 166 (buffer) => buffer.pointers[0], 167 (buf) => ({ ...buf, id: buf.pointers[0] }) 168 ) 169 }; 170 } 171 case 'version': { 172 const infolist = data.objects[0] as WeechatObject<WeechatInfoList>; 173 174 return { 175 type: 'FETCH_VERSION', 176 payload: infolist.content.value 177 }; 178 } 179 case 'lines': { 180 const object = data.objects[0] as WeechatObject<WeechatLine[]>; 181 return { 182 type: 'FETCH_LINES', 183 bufferId: object.content[0].buffer, 184 payload: object.content 185 }; 186 } 187 default: 188 console.log('unhandled event!', data.id, data); 189 return undefined; 190 } 191 };