Skip to content

Commit aa8990d

Browse files
add authentication failiure redirection handling
1 parent 655a298 commit aa8990d

6 files changed

Lines changed: 124 additions & 54 deletions

File tree

editor-packages/editor-canvas/canvas-event-target/canvas-event-target.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,19 @@ export function CanvasEventTarget({
100100
// only for mac
101101
if (s.metaKey) {
102102
onZooming(transform_wheel_to_zoom(s));
103+
// TODO: on firefox, cmd + scroll resizes the window zoom level. this should be prevented.
103104
return;
104105
}
105106
}
106107
onPanning(s);
108+
s.event.stopPropagation();
109+
s.event.preventDefault();
110+
},
111+
onWheelStart: (s) => {
112+
onPanningStart(s);
113+
s.event.stopPropagation();
114+
s.event.preventDefault();
107115
},
108-
onWheelStart: onPanningStart,
109116
onWheelEnd: onPanningEnd,
110117
onMove: onPointerMove,
111118
onDragStart: (s) => {

editor/hooks/use-design.ts

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -169,20 +169,39 @@ export function useDesign({
169169
return design;
170170
}
171171

172+
type TUseDesignFile =
173+
| TFetchFileForApp
174+
| { __type: "error"; reason: "no-file" | "no-auth" | "unauthorized" }
175+
| { __type: "loading" };
176+
172177
export function useDesignFile({ file }: { file: string }) {
173-
const [designfile, setDesignFile] = useState<TFetchFileForApp>(null);
178+
const [designfile, setDesignFile] = useState<TUseDesignFile>({
179+
__type: "loading",
180+
});
174181
const fat = useFigmaAccessToken();
175182
useEffect(() => {
176-
if (file && (fat.accessToken || fat.personalAccessToken)) {
177-
async function handle() {
178-
const repo = new FigmaDesignRepository(fat);
179-
const iterator = repo.fetchFile(file);
180-
let next: IteratorResult<TFetchFileForApp>;
181-
while ((next = await iterator.next()).done === false) {
182-
setDesignFile(next.value);
183+
if (file) {
184+
if (fat.accessToken || fat.personalAccessToken) {
185+
async function handle() {
186+
const repo = new FigmaDesignRepository(fat);
187+
const iterator = repo.fetchFile(file);
188+
let next: IteratorResult<TFetchFileForApp>;
189+
while ((next = await iterator.next()).done === false) {
190+
setDesignFile(next.value);
191+
}
183192
}
193+
handle();
194+
} else {
195+
setDesignFile({
196+
__type: "error",
197+
reason: "no-auth",
198+
});
184199
}
185-
handle();
200+
} else {
201+
setDesignFile({
202+
__type: "error",
203+
reason: "no-file",
204+
});
186205
}
187206
}, [file, fat.accessToken]);
188207

editor/pages/_app.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,13 @@ function HeadInjection() {
7979
}}
8080
/>
8181

82+
{/* disable swipe back navigation on safari mac (incomplete implementation.)*/}
83+
<script
84+
dangerouslySetInnerHTML={{
85+
__html: `function init_disable_mac_safari_swipe_back_gesture () { document.body.addEventListener('mousewheel', function(event) { var maxX = this.scrollWidth - this.offsetWidth; var maxY = this.scrollHeight - this.offsetHeight; if (this.scrollLeft + event.deltaX < 0 || this.scrollLeft + event.deltaX > maxX || this.scrollTop + event.deltaY < 0 || this.scrollTop + event.deltaY > maxY) { event.preventDefault(); this.scrollLeft = Math.max(0, Math.min(maxX, this.scrollLeft + event.deltaX)); this.scrollTop = Math.max(0, Math.min(maxY, this.scrollTop + event.deltaY)); } }, false); } window.addEventListener("DOMContentLoaded", init_disable_mac_safari_swipe_back_gesture, false);`,
86+
}}
87+
/>
88+
8289
{/* region Google analytics */}
8390
{/* https://stackoverflow.com/a/62552263 */}
8491
<script

editor/pages/files/[key]/index.tsx

Lines changed: 63 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -29,54 +29,76 @@ export default function FileEntryEditor() {
2929
initialState.type == "success" && initialState.value.history.present;
3030

3131
useEffect(() => {
32-
if (file) {
33-
if (!file.__initial) {
34-
// when full file is loaded, allow editor with user interaction.
35-
setLoading(false);
32+
if (file.__type === "loading") {
33+
return;
34+
}
35+
36+
if (file.__type === "error") {
37+
// handle error by reason
38+
switch (file.reason) {
39+
case "unauthorized":
40+
case "no-auth": {
41+
router.push("/preferences/access-tokens");
42+
break;
43+
}
44+
case "no-file": {
45+
// ignore. might still be fetching file from query param.
46+
break;
47+
}
3648
}
49+
return;
50+
}
3751

38-
let val: EditorSnapshot;
52+
if (!file.__initial) {
53+
// when full file is loaded, allow editor with user interaction.
54+
setLoading(false);
55+
}
3956

40-
// TODO: seed this as well
41-
// ->> file.styles;
57+
let val: EditorSnapshot;
4258

43-
const components = warmup.componentsFrom(file);
44-
const pages = warmup.pagesFrom(file);
59+
// TODO: seed this as well
60+
// ->> file.styles;
4561

46-
if (prevstate) {
47-
val = {
48-
...prevstate,
49-
design: {
50-
...prevstate.design,
51-
pages: pages,
52-
},
53-
selectedPage: warmup.selectedPage(
54-
prevstate,
55-
pages,
56-
prevstate.selectedNodes
57-
),
58-
};
59-
} else {
60-
val = {
61-
selectedNodes: [],
62-
selectedLayersOnPreview: [],
63-
design: {
64-
input: null,
65-
components: components,
66-
// styles: null,
67-
key: filekey,
68-
pages: pages,
69-
},
70-
selectedPage: warmup.selectedPage(prevstate, pages, null),
71-
};
72-
}
62+
const components = warmup.componentsFrom(file);
63+
const pages = warmup.pagesFrom(file);
7364

74-
initialDispatcher({
75-
type: "set",
76-
value: val,
77-
});
65+
if (prevstate) {
66+
val = {
67+
...prevstate,
68+
design: {
69+
...prevstate.design,
70+
pages: pages,
71+
},
72+
selectedPage: warmup.selectedPage(
73+
prevstate,
74+
pages,
75+
prevstate.selectedNodes
76+
),
77+
};
78+
} else {
79+
val = {
80+
selectedNodes: [],
81+
selectedLayersOnPreview: [],
82+
design: {
83+
input: null,
84+
components: components,
85+
// styles: null,
86+
key: filekey,
87+
pages: pages,
88+
},
89+
selectedPage: warmup.selectedPage(prevstate, pages, null),
90+
};
7891
}
79-
}, [filekey, file?.document?.children]);
92+
93+
initialDispatcher({
94+
type: "set",
95+
value: val,
96+
});
97+
}, [
98+
filekey,
99+
file,
100+
file.__type == "file-fetched-for-app" ? file.document?.children : null,
101+
]);
80102

81103
const safe_value = warmup.safestate(initialState);
82104
return (

editor/repository/figma-design-repository/index.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ export type TFetchFileForApp = (
1313
* rather this fetch is a initail fetch. this is used when blocking the user interaction until first initial whole file fetching on first entry.
1414
*/
1515
__initial: boolean;
16+
17+
__type: "file-fetched-for-app";
1618
};
1719

1820
export class FigmaDesignRepository {
@@ -32,18 +34,30 @@ export class FigmaDesignRepository {
3234
switch (next.value.__response_type) {
3335
case "pages":
3436
if (!existing) {
35-
yield { ...next.value, __initial: true } as TFetchFileForApp;
37+
yield {
38+
...next.value,
39+
__initial: true,
40+
__type: "file-fetched-for-app",
41+
} as TFetchFileForApp;
3642
store.upsert(next.value);
3743
}
3844
break;
3945
case "roots":
4046
if (!existing) {
41-
yield { ...next.value, __initial: true } as TFetchFileForApp;
47+
yield {
48+
...next.value,
49+
__initial: true,
50+
__type: "file-fetched-for-app",
51+
} as TFetchFileForApp;
4252
store.upsert(next.value);
4353
}
4454
break;
4555
case "whole":
46-
yield { ...next.value, __initial: false } as TFetchFileForApp;
56+
yield {
57+
...next.value,
58+
__initial: false,
59+
__type: "file-fetched-for-app",
60+
} as TFetchFileForApp;
4761
store.upsert(next.value);
4862
break;
4963
}

editor/scaffolds/editor/skeleton.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ const SkeletonWrap = styled.div`
4040
const LoadingIndicatorContainer = styled.div`
4141
z-index: 100;
4242
user-select: none;
43+
cursor: default;
4344
display: flex;
4445
justify-content: flex-start;
4546
flex-direction: column;

0 commit comments

Comments
 (0)