diff --git a/src-electron/icons/icon.icns b/src-electron/icons/icon.icns index 42db655f..db8a04cc 100644 Binary files a/src-electron/icons/icon.icns and b/src-electron/icons/icon.icns differ diff --git a/src-electron/icons/icon.ico b/src-electron/icons/icon.ico index 3bc58115..0917f60e 100644 Binary files a/src-electron/icons/icon.ico and b/src-electron/icons/icon.ico differ diff --git a/src-electron/icons/icon.png b/src-electron/icons/icon.png index fe87857c..a62e5f21 100644 Binary files a/src-electron/icons/icon.png and b/src-electron/icons/icon.png differ diff --git a/src/App.vue b/src/App.vue index 1fef0b9d..84ff6535 100644 --- a/src/App.vue +++ b/src/App.vue @@ -34,7 +34,7 @@ onAuthStateChanged(auth, (user) => { if (user) { // User is signed in, see docs for a list of available properties // https://firebase.google.com/docs/reference/js/auth.user - console.log("onAuthStateChanged: logged in") + console.log("%conAuthStateChanged: logged in", "border:1px solid green") useAuthStore().setUser(user) getDoc(doc(firestore, "users", user.uid)) @@ -79,7 +79,7 @@ onAuthStateChanged(auth, (user) => { } else { // User is signed out - console.log("onAuthStateChanged: logged out") + console.log("%conAuthStateChanged: logged out", "border:1px solid green") useAuthStore().setUser(undefined) } }); diff --git a/src/layouts/DefaultLayout.vue b/src/layouts/DefaultLayout.vue index a6e18ec4..2fedc249 100644 --- a/src/layouts/DefaultLayout.vue +++ b/src/layouts/DefaultLayout.vue @@ -131,6 +131,9 @@ + Login + Logout + Settings Activate more Features @@ -204,6 +207,7 @@ import {useSuggestionsStore} from "src/stores/suggestionsStore"; import {FeatureIdent} from "src/models/AppFeature"; import {useSettingsStore} from "src/stores/settingsStore" import ToolbarButton from "components/widgets/ToolbarButton.vue"; +import {useAuthStore} from "stores/authStore"; const $q = useQuasar() const router = useRouter() diff --git a/src/layouts/FullPageLayout.vue b/src/layouts/FullPageLayout.vue index 7adb3c56..aada415f 100644 --- a/src/layouts/FullPageLayout.vue +++ b/src/layouts/FullPageLayout.vue @@ -160,6 +160,8 @@ + Login + Logout Settings Activate more Features @@ -235,6 +237,7 @@ import {FeatureIdent} from "src/models/AppFeature"; import {useSettingsStore} from "src/stores/settingsStore" import ToolbarButton from "components/widgets/ToolbarButton.vue"; import {FirebaseCall} from "src/services/firebase/FirebaseCall"; +import {useAuthStore} from "stores/authStore"; const $q = useQuasar() const router = useRouter() diff --git a/src/models/Suggestion.ts b/src/models/Suggestion.ts index 065e1edb..59debc95 100644 --- a/src/models/Suggestion.ts +++ b/src/models/Suggestion.ts @@ -18,7 +18,8 @@ export enum SuggestionType { REDIRECT_HAPPENED_FOR_BOOKMARK = "REDIRECT_HAPPENED_FOR_BOOKMARK", CONTENT_CHANGE = "CONTENT_CHANGE", FEATURE = "FEATURE", - URL = "URL" + URL = "URL", + RESTART="RESTART" } export enum StaticSuggestionIdent { diff --git a/src/pages/SettingsPage.vue b/src/pages/SettingsPage.vue index 3f207930..3ed82f6e 100644 --- a/src/pages/SettingsPage.vue +++ b/src/pages/SettingsPage.vue @@ -22,8 +22,10 @@ - - + + - + @@ -77,7 +80,8 @@ -
+
Tab Switching Time in seconds
@@ -107,7 +111,8 @@
-
+
Warning Thresholds
@@ -169,7 +174,7 @@
- +
@@ -381,24 +386,29 @@
- Switch on experimental features (or off). These feature toggles - are meant for developers - only as they might break functionality and/or destroy data. Once they are considered 'safe enough', they will be - available at the - "experimental features" view on the left. + + To use feature toggles, you need to have a (free) account. - -
-
Developer Mode
-
activates a couple of experimental features and debug insights. You should only use this - if you can live with loosing data. -
-
-
- +
diff --git a/src/pages/SidePanelPage.vue b/src/pages/SidePanelPage.vue index 00c8dcc1..02e2f115 100644 --- a/src/pages/SidePanelPage.vue +++ b/src/pages/SidePanelPage.vue @@ -239,7 +239,7 @@ {{ toolbarTitle(tabsets as Tabset[]) }} - Tabsets are being synced + Tabsets synced via {{LocalStorage.getItem(SYNC_GITHUB_URL)}} @@ -293,7 +293,7 @@ import {useVOnboarding, VOnboardingStep, VOnboardingWrapper} from 'v-onboarding' import {FirebaseCall} from "src/services/firebase/FirebaseCall"; import getScrollTarget = scroll.getScrollTarget; import InfoMessageWidget from "components/widgets/InfoMessageWidget.vue"; -import {SYNC_TYPE, TITLE_IDENT} from "boot/constants"; +import {SYNC_GITHUB_URL, SYNC_TYPE, TITLE_IDENT} from "boot/constants"; import {collection, getDoc, doc, onSnapshot, setDoc, addDoc, getDocs} from "firebase/firestore"; import {firestore} from "boot/firebase"; import {Account} from "src/models/Account"; diff --git a/src/pages/helper/SubscriptionSettings.vue b/src/pages/helper/SubscriptionSettings.vue index 876b0f10..d76a1cf6 100644 --- a/src/pages/helper/SubscriptionSettings.vue +++ b/src/pages/helper/SubscriptionSettings.vue @@ -91,6 +91,7 @@ import {getFirestore} from "firebase/firestore"; import {collection, setDoc, doc, getDocs} from "firebase/firestore"; import userHasClaim from "src/services/stripe/isUserPremium"; import {createCheckoutSession} from "src/services/stripe/createCheckoutSession"; +import {useAuthStore} from "stores/authStore"; const {inBexMode} = useUtils() @@ -120,9 +121,9 @@ watchEffect(() => { const subscribe = async () => { - if (userCredentials.value) { - console.log("xxx", userCredentials.value?.user?.uid) - await createCheckoutSession(userCredentials.value.user?.uid || '') + if (useAuthStore().isAuthenticated()) { + console.log("xxx", useAuthStore().user.uid) + await createCheckoutSession(useAuthStore().user.uid) } } diff --git a/src/pages/helper/SyncingSettings.vue b/src/pages/helper/SyncingSettings.vue index 574b6aa5..81a045ce 100644 --- a/src/pages/helper/SyncingSettings.vue +++ b/src/pages/helper/SyncingSettings.vue @@ -296,7 +296,7 @@ diff --git a/src/router/routes.ts b/src/router/routes.ts index 4aa65394..601d37f0 100644 --- a/src/router/routes.ts +++ b/src/router/routes.ts @@ -19,6 +19,11 @@ const routes: RouteRecordRaw[] = [ component: () => import('layouts/PlainLayout.vue'), children: [{path: '', component: () => import('pages/StartPage.vue')}], }, + { + path: '/login', + component: () => import('layouts/PlainLayout.vue'), + children: [{path: '', component: () => import('pages/mainpanel/FullPageLoginPage.vue')}], + }, { path: '/fullpage', component: () => import('layouts/PlainLayout.vue'), diff --git a/src/services/AppService.ts b/src/services/AppService.ts index 6a9dd091..70c11247 100644 --- a/src/services/AppService.ts +++ b/src/services/AppService.ts @@ -28,7 +28,9 @@ import {useAuthStore} from "stores/authStore"; import {getAuth} from "firebase/auth"; function useGitStore(st: SyncType, su: string | undefined) { - return st && (st === SyncType.GITHUB || st === SyncType.MANAGED_GIT) && su + const isAuthenticated = useAuthStore().isAuthenticated() + console.log("isAuthenticated", isAuthenticated) + return isAuthenticated && st && (st === SyncType.GITHUB || st === SyncType.MANAGED_GIT) && su } class AppService { diff --git a/src/services/persistence/GitPersistentService.ts b/src/services/persistence/GitPersistentService.ts index 96099631..7a608943 100644 --- a/src/services/persistence/GitPersistentService.ts +++ b/src/services/persistence/GitPersistentService.ts @@ -30,7 +30,7 @@ if (typeof self !== 'undefined') { } async function createDir(...segments: string[]) { - //console.log("got segments", segments) + //log("got segments", segments) let prefix = '' for (const segment of segments) { try { @@ -40,7 +40,7 @@ async function createDir(...segments: string[]) { await pfs.mkdir(path) } catch (err: any) { if (!err.toString().startsWith("Error: EEXIST")) { - console.log(err) + log(err) } } } @@ -56,9 +56,11 @@ async function push(dir: string, proxy: string) { ref: 'main', onAuth: () => ({username: LocalStorage.getItem(SYNC_GITHUB_TOKEN) as string || '---'}), }) - console.log(pushResult) + log(pushResult) } +const log = (s: string, ...args) => console.log("%c" + s, "color:#8B4000", ...args) + class GitPersistenceService implements PersistenceService { private db: IDBPDatabase = null as unknown as IDBPDatabase private readonly _dir = "/tabsets"; @@ -70,16 +72,16 @@ class GitPersistenceService implements PersistenceService { async init(syncType: SyncType, url: string | undefined) { if (url) { if (syncType === SyncType.GITHUB) { - console.log("=== initializing github database ===", url) + log("=== initializing github database ===", url) this.db = await this.initDatabase(url, this.genericCorsProxy) - console.log("=== initializing git database: done ===") + log("=== initializing git database: done ===") useUiStore().dbReady = true return Promise.resolve("done") } else if (syncType === SyncType.MANAGED_GIT) { const subscription = LocalStorage.getItem(SUBSCRIPTION_ID_IDENT) as string - console.log("=== initializing managed git ===", url) + log("=== initializing managed git ===", url) this.db = await this.initDatabase("https://tabsets.git/" + subscription, this.tabsetsCorsProxy) - console.log("=== initializing managed git done ===") + log("=== initializing managed git done ===") useUiStore().dbReady = true return Promise.resolve("done") } @@ -94,19 +96,19 @@ class GitPersistenceService implements PersistenceService { console.debug("about to initialize git") const useDir = dir + "-" + Md5.hashStr(url) window.dir = useDir - console.log(useDir); + log(useDir); this.useProxy = proxy try { await pfs.mkdir(useDir); } catch (err: any) { if (!err.toString().startsWith("Error: EEXIST")) { - console.log(err) + log(err) } } // try to get status let status = await git.status({fs, dir: useDir, filepath: 'README.md'}) - console.log(status) + log(status) try { const cloneDef = { @@ -119,9 +121,9 @@ class GitPersistenceService implements PersistenceService { ref: 'main', singleBranch: true, depth: 10, - //onProgress: (val:any) => (console.log("onProgress", val)), - //onMessage: (val:any) => (console.log("onMessage", val)), - onAuthSuccess: () => (console.log("auth: success")), + //onProgress: (val:any) => (log("onProgress", val)), + //onMessage: (val:any) => (log("onMessage", val)), + onAuthSuccess: () => (log("auth: success")), onAuthFailure: (url, auth) => { //forgetSavedPassword(url) if (confirm('Access was denied. Try again?')) { @@ -136,12 +138,12 @@ class GitPersistenceService implements PersistenceService { }, onAuth: () => ({username: LocalStorage.getItem(SYNC_GITHUB_TOKEN) as string || '---'}), } - console.log(`about to clone '${url}' into ${useDir}`, cloneDef) + log(`about to clone '${url}' into ${useDir}`, cloneDef) const cloneRes = await git.clone(cloneDef); - console.log("cloning done") + log("cloning done") return cloneRes } catch (err) { - console.log("got error", err) + log("got error", err) return Promise.reject(err) } } @@ -151,30 +153,30 @@ class GitPersistenceService implements PersistenceService { const dir = "/" + uid() try { //const r = await this.initDatabase( gitRepoUrl, dir, true) - //console.log("got r", r) + //log("got r", r) const remoteInfoDef = { http, corsProxy: this.useProxy, url: gitRepoUrl, onAuthSuccess: () => { - console.log("auth: success") + log("auth: success") return Promise.resolve("success!") }, - onAuthFailure: () => (console.log("auth: failure")), + onAuthFailure: () => (log("auth: failure")), onAuth: () => ({username: LocalStorage.getItem(SYNC_GITHUB_TOKEN) as string || '---'}), } - console.log("checking repo", remoteInfoDef) + log("checking repo", remoteInfoDef) let info = await git.getRemoteInfo2(remoteInfoDef); - console.log(info); + log(info); } catch (e: any) { - console.log("got e", e) + log("got e", e) return Promise.resolve(e.toString()) } //await pfs.unlink(dir) - console.log("success") + log("success") return Promise.resolve("success") } catch (err) { return Promise.resolve("got error: " + err) @@ -188,21 +190,21 @@ class GitPersistenceService implements PersistenceService { */ async loadTabsets(): Promise { - console.log("=== loading tabsets ===") + log("=== loading tabsets ===") // update from git, then read from fs const tabsets: Tabset[] = [] try { await createDir("tabsets") const result: string[] = await pfs.readdir(`${dir}/tabsets`)//, (callback: any) => { - // console.log("callback", result) + // log("callback", result) for (var index in result) { - //console.log("got ts index", index) + //log("got ts index", index) const tabsetId = result[index] const tsDataLocation = `${dir}/tabsets/${tabsetId}/tabset.json` console.debug("tsDataLocation", tsDataLocation) try { const tsData = await pfs.readFile(tsDataLocation) - //console.log("tsData", tsData) + //log("tsData", tsData) const ts = JSON.parse(tsData) as Tabset // make sure some fields are correcly initialized even for old(er) tabsets @@ -226,14 +228,14 @@ class GitPersistenceService implements PersistenceService { tabsets.push(ts) } catch (err) { - console.log("err", err) + log("err", err) } } } catch (err) { console.warn("err", err) } for (const t of tabsets) { - //console.log("adding t", t) + //log("adding t", t) useTabsStore().addTabset(t) } @@ -270,7 +272,7 @@ class GitPersistenceService implements PersistenceService { } }) - console.log(sha) + log(sha) //await push(this._dir); await push(`${dir}`, this.useProxy); return Promise.resolve(undefined); @@ -287,7 +289,7 @@ class GitPersistenceService implements PersistenceService { */ async loadSpaces(): Promise { - console.log("=== loading spaces ===") + log("=== loading spaces ===") // update from git, then read from fs const spaces: Space[] = [] try { @@ -295,15 +297,15 @@ class GitPersistenceService implements PersistenceService { const entitiesName = "spaces" await createDir(entitiesName) const result: string[] = await pfs.readdir(`${dir}/${entitiesName}`)//, (callback: any) => { - //console.log("callback", result) + //log("callback", result) for (var index in result) { - //console.log("got index", index) + //log("got index", index) const entityId = result[index] const tsDataLocation = `${dir}/${entitiesName}/${entityId}/space.json` console.debug("tsDataLocation", tsDataLocation) try { const tsData = await pfs.readFile(tsDataLocation) - //console.log("tsData", tsData) + //log("tsData", tsData) const s = JSON.parse(tsData) as Space //ts.tabs = [] @@ -320,7 +322,7 @@ class GitPersistenceService implements PersistenceService { spaces.push(s) } catch (err) { - console.log("err", err) + log("err", err) } } } catch (err) { @@ -361,7 +363,7 @@ class GitPersistenceService implements PersistenceService { } }) - console.log(sha) + log(sha) //await push(this._dir); await push(`${dir}`, this.useProxy); return Promise.resolve(undefined); diff --git a/src/stores/windowsStore.ts b/src/stores/windowsStore.ts index af2c085b..9e70437f 100644 --- a/src/stores/windowsStore.ts +++ b/src/stores/windowsStore.ts @@ -128,7 +128,7 @@ export const useWindowsStore = defineStore('windows', () => { const indexFromDb = tabsetWindowFromStorage.index const indicesDiffer = indexFromDb !== index let indexToUse = index++ - console.log("indicesDiffer", indicesDiffer, tabsetWindowFromStorage.id, indexFromDb, indexToUse) + //console.log("indicesDiffer", indicesDiffer, tabsetWindowFromStorage.id, indexFromDb, indexToUse) // if (usedIndices.indexOf(indexToUse) >= 0) { // const candiate = indexToUse @@ -149,7 +149,7 @@ export const useWindowsStore = defineStore('windows', () => { const inCurrentWindows = windows.find(w => w.id === tabsetWindowFromStorage.id) !== undefined - console.log(`assigned window #${tabsetWindowFromStorage.id} (name: ${tabsetWindowFromStorage.title}): ${indexFromDb} -> ${tabsetWindowFromStorage.index}, open: ${inCurrentWindows}`) + console.debug(`assigned window #${tabsetWindowFromStorage.id} (name: ${tabsetWindowFromStorage.title}): ${indexFromDb} -> ${tabsetWindowFromStorage.index}, open: ${inCurrentWindows}`) }) for (const id of allWindows.value.keys()) { const w = allWindows.value.get(id) @@ -353,70 +353,6 @@ export const useWindowsStore = defineStore('windows', () => { }) } - async function moveWindow(rows: object[], windowIndex: number, oldIndex: number, newIndex: number) { - console.log("moving window", windowIndex) - const theWindows = getSortedWindows(windowForId); - - console.log("*** theWindows", theWindows) - - console.log("moving", windowIndex, oldIndex, newIndex) - if (oldIndex >= 0 && rows.length > 0) { - console.log("old rows", _.map(rows, r => r.id + ":" + r.index)) - - const newOrder = _.map(rows, r => r.id as number) - const startIndex = rows[0]['index' as keyof object] - let index = startIndex - console.log("newOrder", newOrder, startIndex) - for (const r of newOrder) { - await updateWindowIndex(r, index++) - } - } - - //let foundRow = undefined - // for (let i = 0; i < theWindows.length - 1; i++) { - // const windowOriginalIndex = index - // if (theWindows[i + 1].index === windowOriginalIndex) { - // // i = row before element to move up - // // i+1 element to move up - // foundRow = i - // - // const windowToMoveDown: chrome.windows.Window | undefined = useWindowsStore().currentWindowForId(theWindows[i].cw.id || -1) - // const windowToMoveUp: chrome.windows.Window | undefined = useWindowsStore().currentWindowForId(theWindows[i + 1].cw.id || -1) - // - // console.log("windowToMoveDown", windowToMoveDown) - // console.log("windowToMoveUp", windowToMoveUp) - // - // const indexToSwitch = theWindows[i].index // element before - // console.log("found index to switch", indexToSwitch) - // - // console.log("setting", i, windowOriginalIndex) - // if (theWindows[i].windowFromStore) { - // // @ts-ignore - // theWindows[i].windowFromStore.index = windowOriginalIndex - // } - // - // console.log("setting", i + 1, indexToSwitch) - // if (theWindows[i + 1].windowFromStore) { - // // @ts-ignore - // theWindows[i + 1].windowFromStore.index = indexToSwitch - // } - // - // if (windowToMoveDown) { - // console.log("moving down", i) - // await useWindowsStore().upsertWindow(windowToMoveDown, theWindows[i].windowFromStore?.title, windowOriginalIndex) - // } - // if (windowToMoveUp) { - // await useWindowsStore().upsertWindow(windowToMoveUp, theWindows[i + 1].windowFromStore?.title, indexToSwitch) - // } - // - // } - // if (foundRow) { - // break - // } - // - // } - } - async function updateWindowIndex(windowId: number, indexToUse: number) { console.log("updating window index", windowId, indexToUse) return storage.getWindow(windowId).then(w => {