Skip to content

Commit 2b99ba1

Browse files
committed
added mainReducer.ts
1 parent 6ba70ac commit 2b99ba1

File tree

1 file changed

+243
-0
lines changed

1 file changed

+243
-0
lines changed

src/app/reducers/mainReducer.ts

Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
/* eslint-disable no-param-reassign */
2+
import produce from 'immer';
3+
import * as types from '../constants/actionTypes.ts';
4+
5+
6+
export default (state, action) => produce(state, draft => {
7+
const { port, currentTab, tabs } = draft;
8+
const {
9+
hierarchy,
10+
snapshots,
11+
mode,
12+
intervalId,
13+
viewIndex,
14+
sliderIndex,
15+
} = tabs[currentTab] || {};
16+
17+
18+
// gabi and nate :: function that find the index in the hierarchy and extract the name of the equivalent index to add to the post message
19+
const findName = (index, hierarchy) => {
20+
if (hierarchy.index == index) {
21+
return hierarchy.name;
22+
}
23+
24+
const hierarchyChildArray = [];
25+
for (const hierarchyChild of hierarchy.children) {
26+
hierarchyChildArray.push(findName(index, hierarchyChild));
27+
}
28+
for (const hierarchyChildName of hierarchyChildArray) {
29+
if (hierarchyChildName) {
30+
return hierarchyChildName;
31+
}
32+
}
33+
};
34+
35+
switch (action.type) {
36+
case types.MOVE_BACKWARD: {
37+
if (snapshots.length > 0 && sliderIndex > 0) {
38+
const newIndex = sliderIndex - 1;
39+
// gabi and nate :: find the name by the newIndex parsing through the hierarchy to send to background.js the current name in the jump action
40+
const nameFromIndex = findName(newIndex, hierarchy);
41+
42+
port.postMessage({
43+
action: 'jumpToSnap',
44+
payload: snapshots[newIndex],
45+
index: newIndex,
46+
name: nameFromIndex,
47+
tabId: currentTab,
48+
});
49+
clearInterval(intervalId);
50+
51+
tabs[currentTab].sliderIndex = newIndex;
52+
tabs[currentTab].playing = false;
53+
}
54+
break;
55+
}
56+
case types.MOVE_FORWARD: {
57+
if (sliderIndex < snapshots.length - 1) {
58+
const newIndex = sliderIndex + 1;
59+
// gabi and nate :: find the name by the newIndex parsing through the hierarchy to send to background.js the current name in the jump action
60+
const nameFromIndex = findName(newIndex, hierarchy);
61+
62+
port.postMessage({
63+
action: 'jumpToSnap',
64+
index: newIndex,
65+
name: nameFromIndex,
66+
payload: snapshots[newIndex],
67+
tabId: currentTab,
68+
});
69+
70+
tabs[currentTab].sliderIndex = newIndex;
71+
72+
// message is coming from the user
73+
if (!action.payload) {
74+
clearInterval(intervalId);
75+
tabs[currentTab].playing = false;
76+
}
77+
}
78+
break;
79+
}
80+
case types.SLIDER_ZERO: {
81+
// gabi and nate :: reset name to 0 to send to background.js the current name in the jump action
82+
port.postMessage({
83+
action: 'jumpToSnap',
84+
index: 0,
85+
name: 0,
86+
payload: snapshots[0],
87+
tabId: currentTab,
88+
});
89+
tabs[currentTab].sliderIndex = 0;
90+
break;
91+
}
92+
case types.CHANGE_VIEW: {
93+
// unselect view if same index was selected
94+
if (viewIndex === action.payload) tabs[currentTab].viewIndex = -1;
95+
else tabs[currentTab].viewIndex = action.payload;
96+
break;
97+
}
98+
case types.CHANGE_SLIDER: {
99+
// gabi and nate :: finds the name by the action.payload, parsing through the hierarchy to send to background.js the current name in the jump action
100+
const nameFromIndex = findName(action.payload, hierarchy);
101+
102+
port.postMessage({
103+
action: 'jumpToSnap',
104+
payload: snapshots[action.payload],
105+
index: action.payload,
106+
name: nameFromIndex,
107+
tabId: currentTab,
108+
});
109+
tabs[currentTab].sliderIndex = action.payload;
110+
break;
111+
}
112+
case types.EMPTY: {
113+
port.postMessage({ action: 'emptySnap', tabId: currentTab });
114+
tabs[currentTab].sliderIndex = 0;
115+
tabs[currentTab].viewIndex = -1;
116+
tabs[currentTab].playing = false;
117+
// gabi :: activate empty mode
118+
tabs[currentTab].mode.empty = true;
119+
// gabi :: record snapshot of page initial state
120+
tabs[currentTab].initialSnapshot.push(tabs[currentTab].snapshots[0]);
121+
// gabi :: reset snapshots to page last state recorded
122+
tabs[currentTab].snapshots = [tabs[currentTab].snapshots[tabs[currentTab].snapshots.length - 1]];
123+
// gabi :: record hierarchy of page initial state
124+
tabs[currentTab].initialHierarchy = { ...tabs[currentTab].hierarchy };
125+
tabs[currentTab].initialHierarchy.children = [];
126+
// gabi :: reset hierarchy
127+
tabs[currentTab].hierarchy.children = [];
128+
// gabi :: reset hierarchy to page last state recorded
129+
tabs[currentTab].hierarchy.stateSnapshot = tabs[currentTab].snapshots[0];
130+
// gabi :: reset currLocation to page last state recorded
131+
tabs[currentTab].currLocation = tabs[currentTab].hierarchy;
132+
// gabi :: reset index
133+
tabs[currentTab].index = 0;
134+
// gabi :: reset currParent plus current state
135+
tabs[currentTab].currParent = 1;
136+
// gabi :: reset currBranch
137+
tabs[currentTab].currBranch = 0;
138+
break;
139+
}
140+
case types.SET_PORT: {
141+
draft.port = action.payload;
142+
break;
143+
}
144+
case types.IMPORT: {
145+
port.postMessage({ action: 'import', payload: action.payload, tabId: currentTab });
146+
tabs[currentTab].snapshots = action.payload;
147+
break;
148+
}
149+
case types.TOGGLE_MODE: {
150+
mode[action.payload] = !mode[action.payload];
151+
const newMode = mode[action.payload];
152+
let actionText;
153+
switch (action.payload) {
154+
case 'paused':
155+
actionText = 'setPause';
156+
break;
157+
case 'locked':
158+
actionText = 'setLock';
159+
break;
160+
case 'persist':
161+
actionText = 'setPersist';
162+
break;
163+
default:
164+
break;
165+
}
166+
port.postMessage({ action: actionText, payload: newMode, tabId: currentTab });
167+
break;
168+
}
169+
case types.PAUSE: {
170+
clearInterval(intervalId);
171+
tabs[currentTab].playing = false;
172+
tabs[currentTab].intervalId = null;
173+
break;
174+
}
175+
case types.PLAY: {
176+
tabs[currentTab].playing = true;
177+
tabs[currentTab].intervalId = action.payload;
178+
break;
179+
}
180+
case types.INITIAL_CONNECT: {
181+
const { payload } = action;
182+
Object.keys(payload).forEach(tab => {
183+
// check if tab exists in memory
184+
// add new tab
185+
tabs[tab] = {
186+
...payload[tab],
187+
sliderIndex: 0,
188+
viewIndex: -1,
189+
intervalId: null,
190+
playing: false,
191+
};
192+
});
193+
194+
// only set first tab if current tab is non existent
195+
const firstTab = parseInt(Object.keys(payload)[0], 10);
196+
if (currentTab === undefined || currentTab === null) draft.currentTab = firstTab;
197+
break;
198+
}
199+
case types.NEW_SNAPSHOTS: {
200+
const { payload } = action;
201+
202+
Object.keys(tabs).forEach(tab => {
203+
if (!payload[tab]) {
204+
delete tabs[tab];
205+
} else {
206+
const { snapshots: newSnaps } = payload[tab];
207+
tabs[tab] = {
208+
...tabs[tab],
209+
...payload[tab],
210+
sliderIndex: newSnaps.length - 1,
211+
};
212+
}
213+
});
214+
215+
// only set first tab if current tab is non existent
216+
const firstTab = parseInt(Object.keys(payload)[0], 10);
217+
if (currentTab === undefined || currentTab === null) draft.currentTab = firstTab;
218+
break;
219+
}
220+
case types.SET_TAB: {
221+
if (typeof action.payload === 'number') {
222+
draft.currentTab = action.payload;
223+
break;
224+
} else if (typeof action.payload === 'object') {
225+
draft.currentTab = action.payload.tabId;
226+
break;
227+
}
228+
break;
229+
}
230+
case types.DELETE_TAB: {
231+
delete draft.tabs[action.payload];
232+
if (draft.currentTab === action.payload) {
233+
// if the deleted tab was set to currentTab, replace currentTab with
234+
// the first tabId within tabs obj
235+
const newCurrentTab = parseInt(Object.keys(draft.tabs)[0], 10);
236+
draft.currentTab = newCurrentTab;
237+
}
238+
break;
239+
}
240+
default:
241+
throw new Error(`nonexistent action: ${action.type}`);
242+
}
243+
});

0 commit comments

Comments
 (0)