diff --git a/e2e/AboutPage.ts b/e2e/AboutPage.ts index 8f0373d5..7862c886 100644 --- a/e2e/AboutPage.ts +++ b/e2e/AboutPage.ts @@ -35,23 +35,4 @@ export class AboutPage extends TabsetPage { await expect(this.page.locator('text=Add new Tabset')).not.toBeVisible() } - async submitNewTabsetDialog(tabsetName: string): Promise { - await this.createFirstTabsetBtn.click() - await this.newTabsetName.fill(tabsetName) - // await this.newTabsetAutoAdd.uncheck() - await this.fillByTestId(this.page, 'newTabsetName', tabsetName) - await this.newTabsetNameSubmit.click() - return new TabsetTestPage(this.page, this.extensionId) - } - - async submitAddUrlDialog(url: string): Promise { - await this.screenshot(this.page, 'addTabset','beforeAddUrl.png'); - await this.addUrlDialogBtn.click() - //await this.page.waitForSelector('text="NEW TAB"') - //await this.page.locator('text="NEW TAB"').click() - await this.addUrlDialogSubmit.fill(url) - await this.screenshot(this.page, 'addTabset','afterAddUrl.png'); - await this.submitUrlDialogSubmit.click() - return new TabsetTestPage(this.page, this.extensionId) - } } diff --git a/e2e/PageDefs/SidePanelWelcomePageDefinition.ts b/e2e/PageDefs/SidePanelWelcomePageDefinition.ts index b40fa780..d191cb08 100644 --- a/e2e/PageDefs/SidePanelWelcomePageDefinition.ts +++ b/e2e/PageDefs/SidePanelWelcomePageDefinition.ts @@ -27,25 +27,4 @@ export class SidePanelWelcomePageDefinition extends TabsetPageDefinition { //await expect(this.page.locator('text=Add')).not.toBeVisible() } - async submitNewTabsetDialog(tabsetName: string) { - console.log("page url 1", this.page.url()) - await this.newTabsetName.fill(tabsetName) - await this.addTabsetSubmitBtn.click() - //await delay(2000) - console.log(`checking for chrome-extension://${this.extensionId}/www/index.html#/sidepanel`) - await this.page.waitForURL("**\/sidepanel**") - console.log("page url 2", this.page.url()) - //return Promise.resolve(new SidePanelPageDefinition(this.page, this.extensionId)) - } - - // async submitAddUrlDialog(url: string): Promise { - // await this.screenshot(this.page, 'addTabset','beforeAddUrl.png'); - // await this.addUrlDialogBtn.click() - // //await this.page.waitForSelector('text="NEW TAB"') - // //await this.page.locator('text="NEW TAB"').click() - // await this.addUrlDialogSubmit.fill(url) - // await this.screenshot(this.page, 'addTabset','afterAddUrl.png'); - // await this.submitUrlDialogSubmit.click() - // return new TabsetTestPage(this.page, this.extensionId) - // } } diff --git a/package.json b/package.json index 51f820cc..10b95fc6 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "@editorjs/editorjs": "^2.30.5", "@editorjs/header": "^2.8.7", "@extractus/feed-extractor": "^7.1.3", + "@he-tree/vue": "^2.8.7", "@intlify/unplugin-vue-i18n": "^4.0.0", "@quasar/extras": "^1.16.12", "@sentry/browser": "^8.32.0", @@ -93,6 +94,7 @@ "vue": "^3.5.10", "vue-draggable-next": "^2.2.1", "vue-grid-layout-v3": "^3.0.3", + "vue-highlight-words": "^3.0.1", "vue-i18n": "^10.0.3", "vue-json-pretty": "^2.4.0", "vue-router": "^4.4.3", diff --git a/src/bookmarks b/src/bookmarks index 481342af..35a4ae3e 160000 --- a/src/bookmarks +++ b/src/bookmarks @@ -1 +1 @@ -Subproject commit 481342afcdb242cf91e1a7c95cc419363e049407 +Subproject commit 35a4ae3ee6de50066c5cd08e0281b862ded05f9d diff --git a/src/components/TabsAsTree.vue b/src/components/TabsAsTree.vue index d6247bfd..f0f2f0df 100644 --- a/src/components/TabsAsTree.vue +++ b/src/components/TabsAsTree.vue @@ -1,23 +1,51 @@ @@ -29,10 +57,14 @@ import {useBookmarksStore} from "src/bookmarks/stores/bookmarksStore"; import {useNotificationsStore} from "src/stores/notificationsStore"; import {useNotificationHandler} from "src/core/services/ErrorHandler"; import NavigationService from "src/services/NavigationService"; -import DeleteBookmarkFolderDialog from "src/bookmarks/dialogues/DeleteBookmarkFolderDialog.vue"; import _ from "lodash" import {TreeNode} from "src/bookmarks/models/Tree"; import {useTabsetsStore} from "src/tabsets/stores/tabsetsStore"; +import Highlighter from 'vue-highlight-words' +import {useSettingsStore} from "stores/settingsStore"; +import {useUtils} from "src/core/services/Utils"; + +const {favIconFromUrl} = useUtils() const $q = useQuasar(); const localStorage = useQuasar().localStorage @@ -40,8 +72,11 @@ const localStorage = useQuasar().localStorage const mouseHover = ref(false) const selected = ref('') const deleteButtonId = ref('') -const nodesToUrl = ref>(new Map()) +const nodesToUrl = ref>(new Map()) const bookmarksPermissionGranted = ref(undefined) +const filterRef = ref(null) +const filter = ref('') +const loading = ref(true) const {handleSuccess, handleError} = useNotificationHandler() @@ -70,22 +105,23 @@ function createNodes(tabs: object[], level = 0): TreeNode[] { return (segments && segments.length > level + 1 && segments[level] === name) }) const children: TreeNode[] = createNodes(filteredTabs, level + 1) - // console.log("calculated children", children.length) + // console.log("calculated children", children.length) const newNodeId = uid() - let url = t['protocol' as keyof object] + "//" + t['hostname' as keyof object] + let url: string = t['protocol' as keyof object] + "//" + t['hostname' as keyof object] for (let i = 1; i <= level; i++) { url += "/" + t['segments' as keyof object][i] } children.length === 0 ? nodesToUrl.value.set(newNodeId, t['url' as keyof object]) : nodesToUrl.value.set(newNodeId, url) - const newNode = new TreeNode(newNodeId, name as string, name as string, undefined, "", children) + const newNode = new TreeNode(newNodeId, name as string, name as string, url, "", children, level) nodes.push(newNode) } return nodes } watchEffect(() => { + loading.value = true const tabs: object[] = [] for (const ts of useTabsetsStore().tabsets.values()) { for (const t of ts.tabs) { @@ -110,8 +146,13 @@ watchEffect(() => { } } const nodes = createNodes(tabs, 0); - console.log("nodes", nodes) tabNodes.value = JSON.parse(JSON.stringify(nodes)) + // console.log("v", tabNodes.value) + loading.value = false +}) + +watchEffect(() => { + console.log("loading", loading.value) }) watchEffect(() => { @@ -141,17 +182,47 @@ $q.loadingBar.setDefaults({ position: 'bottom' }) -const deleteBookmarksFolderDialog = () => { - $q.dialog({ - component: DeleteBookmarkFolderDialog, - componentProps: { - folderId: selected.value - } - }) +const resetFilter = () => { + filter.value = '' + if (filterRef.value) { + // @ts-ignore + filterRef.value.focus() + } } +const filterMethod = (node: TreeNode, filter: any): boolean => + (node.url !== undefined) && (node.url.toLowerCase().indexOf(filter.toLowerCase()) > -1) + + const entered = (b: boolean) => mouseHover.value = b +const getFaviconUrl = (n: TreeNode) => { + // if (!useSettingsStore().isEnabled('noDDG')) { + let theUrl = n.url || '' + // let theRealUrl + // try { + // theRealUrl = new URL(theUrl) + // } catch (err) { + // if (!theUrl.startsWith('http')) { + // theUrl = 'https://' + theUrl + // try { + // theRealUrl = new URL(theUrl) + // } catch (err) { + // } + // } + // } + // return theRealUrl ? "https://icons.duckduckgo.com/ip3/" + theRealUrl.hostname + ".ico" : 'favicon-unknown-32x32.png' + //} + + //const chromeTab = tab?.chromeTab + if (theUrl.startsWith("chrome")) { + return '' + } + if (!useSettingsStore().isEnabled('noDDG')) { + return favIconFromUrl(theUrl) + } + return '' +}