Skip to content

Commit ba7afea

Browse files
committed
feat: create new extension page app for ios
1 parent 9dbf6ab commit ba7afea

5 files changed

Lines changed: 160 additions & 16 deletions

File tree

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<script>
2+
import { onMount } from "svelte";
3+
import { blur } from "svelte/transition";
4+
import { log, notifications, settings, state } from "./store.js";
5+
import Settings from "./Components/Settings.svelte";
6+
import Notification from "./Components/Notification.svelte";
7+
import logo from "../shared/img/logo.svg?raw";
8+
import { sendNativeMessage } from "../shared/native.js";
9+
10+
const logger = [];
11+
12+
$: $log.some((item) => {
13+
if (!logger.includes(item)) {
14+
// eslint-disable-next-line no-console -- not arbitrary console command
15+
console[item.type](item.message);
16+
logger.push(item);
17+
}
18+
});
19+
20+
onMount(async () => {
21+
log.add("Requesting initialization data", "info", false);
22+
const initData = await sendNativeMessage({ name: "PAGE_INIT_DATA" });
23+
if (initData.error) return console.error(initData.error);
24+
await settings.init(initData);
25+
state.remove("init");
26+
state.loadUrlState();
27+
// Since now the only view on iOS
28+
state.add("settings");
29+
});
30+
</script>
31+
32+
{#if $state.includes("init")}
33+
<div class="initializer" out:blur={{ duration: 350 }}>
34+
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
35+
{@html logo}
36+
{#if $state.includes("init-error")}
37+
<span>Failed to initialize app, check the browser console</span>
38+
{:else}
39+
<span>Initializing app...</span>
40+
{/if}
41+
</div>
42+
{/if}
43+
<ul>
44+
{#each $notifications as item (item.id)}
45+
<Notification on:click={() => notifications.remove(item.id)} {item} />
46+
{/each}
47+
</ul>
48+
{#if $state.includes("settings")}
49+
<Settings platform="ios" />
50+
{/if}
51+
52+
<style>
53+
.initializer {
54+
align-items: center;
55+
background-color: var(--color-bg-primary);
56+
display: flex;
57+
flex-direction: column;
58+
height: 100%;
59+
justify-content: center;
60+
left: 0;
61+
opacity: 1;
62+
position: absolute;
63+
top: 0;
64+
visibility: visible;
65+
width: 100%;
66+
z-index: 99;
67+
}
68+
69+
.initializer :global(svg) {
70+
height: 1.5rem;
71+
margin-bottom: 0.5rem;
72+
}
73+
74+
.initializer span {
75+
color: var(--text-color-secondary);
76+
font: var(--text-medium);
77+
}
78+
79+
div:not(.initializer) {
80+
display: flex;
81+
flex: 1 0 0;
82+
overflow: hidden;
83+
}
84+
85+
ul {
86+
bottom: 1rem;
87+
left: 50%;
88+
position: fixed;
89+
transform: translateX(-50%);
90+
z-index: 98;
91+
}
92+
</style>

src/ext/extension-page/app.css

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,15 @@ html {
33
height: 100vh;
44
height: 100svh; /* safari 15.4 */
55
overflow: hidden;
6+
overscroll-behavior: none;
7+
}
8+
9+
/* ios */
10+
@supports (-webkit-touch-callout: none) {
11+
html {
12+
height: auto;
13+
overflow: visible;
14+
}
615
}
716

817
body {

src/ext/extension-page/main.js

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import "../shared/reset.css";
22
import "../shared/variables.css";
33
import "./app.css";
44
import App from "./App.svelte";
5+
import Appios from "./Appios.svelte";
56

67
// vite feat that only import in dev mode
78
if (import.meta.env.MODE === "development") {
@@ -14,8 +15,26 @@ if (import.meta.env.MODE === "development") {
1415
}
1516
}
1617

17-
const app = new App({
18-
target: document.getElementById("app"),
19-
});
18+
let app;
19+
const target = document.getElementById("app");
20+
if (import.meta.env.MODE === "development") {
21+
const platform = await browser.runtime.getPlatformInfo();
22+
// @ts-ignore -- incomplete polyfill types
23+
if (platform.os === "ios") {
24+
app = new Appios({ target });
25+
} else {
26+
app = new App({ target });
27+
}
28+
} else {
29+
if (import.meta.env.SAFARI_PLATFORM === "ios") {
30+
app = new Appios({ target });
31+
} else {
32+
app = new App({ target });
33+
}
34+
}
35+
36+
// const app = new App({
37+
// target: document.getElementById("app"),
38+
// });
2039

2140
export default app;

src/ext/extension-page/store.js

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ function stateStore() {
3737
// store oldState to see how state transitioned
3838
// ex. if (newState === foo && oldState === bar) baz();
3939
let oldState = [];
40-
const add = (stateModifier) =>
40+
const add = (stateModifier) => {
4141
update((state) => {
4242
// list of acceptable states, mostly for state definition tracking
4343
const states = [
@@ -68,7 +68,14 @@ function stateStore() {
6868
);
6969
return state;
7070
});
71-
const remove = (stateModifier) =>
71+
// URL hash handle
72+
const params = new URLSearchParams(location.hash.slice(1));
73+
if (["settings"].includes(stateModifier)) {
74+
params.set("state", stateModifier);
75+
location.hash = params.toString();
76+
}
77+
};
78+
const remove = (stateModifier) => {
7279
update((state) => {
7380
// save pre-changed state to oldState var
7481
oldState = [...state];
@@ -84,20 +91,38 @@ function stateStore() {
8491
);
8592
return state;
8693
});
94+
// URL hash handle
95+
const params = new URLSearchParams(location.hash.slice(1));
96+
const state = params.get("state");
97+
if (state === stateModifier) {
98+
params.delete("state");
99+
location.hash = params.toString();
100+
}
101+
};
87102
const getOldState = () => oldState;
88-
return { subscribe, add, getOldState, remove };
103+
// URL hash handle
104+
const loadUrlState = () => {
105+
const params = new URLSearchParams(location.hash.slice(1));
106+
const state = params.get("state");
107+
state && add(state);
108+
};
109+
return { subscribe, add, getOldState, remove, loadUrlState };
89110
}
90111
export const state = stateStore();
91112

92113
function settingsStore() {
93114
const { subscribe, update, set } = writable({});
94115
const init = async (initData) => {
95-
// import legacy settings data just one-time
96-
await settingsStorage.legacyImport();
116+
if (import.meta.env.SAFARI_PLATFORM === "mac") {
117+
// import legacy settings data just one-time
118+
await settingsStorage.legacyImport();
119+
}
97120
// for compatibility with legacy getting names only
98121
// once all new name is used, use settingsStorage.get()
99122
const settings = await settingsStorage.legacyGet();
100-
console.info("store.js settingsStore init", initData, settings);
123+
if (import.meta.env.MODE === "development") {
124+
console.info("store.js settingsStore init", initData, settings);
125+
}
101126
set({ ...initData, ...settings });
102127
// sync popup, backgound, etc... settings changes
103128
settingsStorage.onChangedSettings((sets, area) => {
@@ -135,6 +160,7 @@ function settingsStore() {
135160
// for compatibility with legacy setting names only
136161
// once all new name is used, use settingsStorage.set()
137162
settingsStorage.legacySet({ [key]: value }); // Durable Storage
163+
settingsStorage.set({ [key]: value }); // Durable Storage
138164
// temporarily keep the old storage method until it is confirmed that all dependencies are removed
139165
updateSingleSettingOld(key, value);
140166
};

xcode/Ext-Safari/SafariWebExtensionHandler.swift

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -186,13 +186,11 @@ class SafariWebExtensionHandler: NSObject, NSExtensionRequestHandling {
186186
}
187187
}
188188
else if name == "PAGE_INIT_DATA" {
189-
#if os(macOS)
190-
if let initData = getInitData(), checkDefaultDirectories() {
191-
response.userInfo = [SFExtensionMessageKey: initData]
192-
} else {
193-
response.userInfo = [SFExtensionMessageKey: ["error": "failed to get init data"]]
194-
}
195-
#endif
189+
if let initData = getInitData(), checkDefaultDirectories() {
190+
response.userInfo = [SFExtensionMessageKey: initData]
191+
} else {
192+
response.userInfo = [SFExtensionMessageKey: ["error": "failed to get init data"]]
193+
}
196194
}
197195
else if name == "PAGE_LEGACY_IMPORT" {
198196
#if os(macOS)

0 commit comments

Comments
 (0)