Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/_locales/dict.setup-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2538,6 +2538,9 @@ Vous pouvez également définir des préfixes pour chaque type de commande pour
en: 'Keep searching after triggering the context menu option',
fr: 'Continuer à chercher après avoir déclenché l’option du menu contextuel',
},
'settings.search_all_panels_default': {
en: 'Search all panels by default (invert "/" prefix behavior)',
},
'settings.search.shortcuts': {
en: 'Shortcuts',
de: 'Tastenkombinationen',
Expand Down
1 change: 1 addition & 0 deletions src/defaults/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ export const DEFAULT_SETTINGS: SettingsState = {
searchPanelSwitch: 'same_type',
searchTabSwitch: false,
searchMenuTrig: false,
searchAllPanelsDefault: false,
searchBookmarksShortcut: '',
searchHistoryShortcut: '',
searchInputTimeout: 300,
Expand Down
6 changes: 6 additions & 0 deletions src/page.setup/components/settings.search.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ section(ref="el")
dbg="searchMenuTrig"
:default="DEFAULT_SETTINGS.searchMenuTrig"
@update:value="Settings.saveDebounced(150)")
ToggleField(
label="settings.search_all_panels_default"
v-model:value="Settings.state.searchAllPanelsDefault"
dbg="searchAllPanelsDefault"
:default="DEFAULT_SETTINGS.searchAllPanelsDefault"
@update:value="Settings.saveDebounced(150)")
InfoField(
label="settings.search.shortcuts"
:value="translate('settings.search.shortcuts.note')")
Expand Down
51 changes: 36 additions & 15 deletions src/services/search.fg.tabs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,51 +60,72 @@ export function onTabsSearch(activePanel: Panel): void {
}
}

export function onTabsSearchNext(panel?: Panel): void {
if (!panel) panel = Sidebar.panelsById[Sidebar.activePanelId]
if (!Utils.isTabsPanel(panel) || !panel.filteredTabs) return
function getFilteredTabs(panel?: Panel): Tab[] {
let filteredTabs: Tab[] = []
if (Search.reactive.allPanels) {
for (const p of Sidebar.panels) {
if (Utils.isTabsPanel(p) && p.filteredTabs) {
filteredTabs.push(...p.filteredTabs)
}
}
} else {
if (!panel) panel = Sidebar.panelsById[Sidebar.activePanelId]
if (Utils.isTabsPanel(panel) && panel.filteredTabs) {
filteredTabs = panel.filteredTabs
}
}
return filteredTabs
}

export function onTabsSearchNext(panel?: Panel): void {
const filteredTabs = getFilteredTabs(panel)
if (!filteredTabs.length) return

const selId = Selection.getFirst()
let index = panel.filteredTabs.findIndex(t => t.id === selId)
let index = filteredTabs.findIndex(t => t.id === selId)

index += 1
if (index < 0 || index >= panel.filteredTabs.length) return
if (index < 0 || index >= filteredTabs.length) return

Selection.resetSelection()
const tab = panel.filteredTabs[index]
const tab = filteredTabs[index]
if (tab) {
Selection.selectTab(tab.id)
Tabs.scrollToTab(tab.id, true)
}
}

export function onTabsSearchPrev(panel?: Panel): void {
if (!panel) panel = Sidebar.panelsById[Sidebar.activePanelId]
if (!Utils.isTabsPanel(panel) || !panel.filteredTabs) return
const filteredTabs = getFilteredTabs(panel)

if (!filteredTabs.length) return

const selId = Selection.getFirst()
let index = panel.filteredTabs.findIndex(t => t.id === selId)
let index = filteredTabs.findIndex(t => t.id === selId)

if (index === -1 && panel.filteredTabs.length) {
index = panel.filteredTabs.length
if (index === -1 && filteredTabs.length) {
index = filteredTabs.length
}

index -= 1
if (index < 0 || index >= panel.filteredTabs.length) return
if (index < 0 || index >= filteredTabs.length) return

Selection.resetSelection()
const tab = panel.filteredTabs[index]
const tab = filteredTabs[index]
if (tab) {
Selection.selectTab(tab.id)
Tabs.scrollToTab(tab.id, true)
}
}

export function onTabsSearchEnter(panel?: Panel): void {
if (!Utils.isTabsPanel(panel)) return
// If in all panels mode, we don't strictly require the passed panel to be valid.
if (!Search.reactive.allPanels && !Utils.isTabsPanel(panel)) return

// Try to find in another panel
if (Search.query && !panel.filteredTabs?.length) return findInAnotherPanel()
if (Search.query && !Search.reactive.allPanels && (!panel || !Utils.isTabsPanel(panel) || !panel.filteredTabs?.length)) {
return findInAnotherPanel()
}

const selId = Selection.getFirst()
const tab = Tabs.byId[selId]
Expand Down
64 changes: 44 additions & 20 deletions src/services/search.fg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export interface SearchState {
barIsFilled: boolean
active: boolean
rawQuery: string
allPanels: boolean
}

export interface SearchShortcut {
Expand All @@ -45,6 +46,7 @@ export let reactive: SearchState = {
barIsFilled: false,
active: false,
rawQuery: '',
allPanels: false,
}

export let active = false
Expand Down Expand Up @@ -114,6 +116,10 @@ export function next(): void {
if (!Search.reactive.barIsShowed) return
if (Menu.isOpen) return Menu.selectOption(1)

if (reactive.allPanels) {
return SearchTabs.onTabsSearchNext(undefined)
}

const actPanel = Sidebar.panelsById[Sidebar.activePanelId]
if (!actPanel) return

Expand All @@ -135,6 +141,10 @@ export function prev(): void {
if (!Search.reactive.barIsShowed) return
if (Menu.isOpen) return Menu.selectOption(-1)

if (reactive.allPanels) {
return SearchTabs.onTabsSearchPrev(undefined)
}

const actPanel = Sidebar.panelsById[Sidebar.activePanelId]
if (!actPanel) return

Expand All @@ -154,11 +164,10 @@ export function prev(): void {

export function enter(): void {
if (!Search.reactive.barIsShowed) return
if (Menu.isOpen) return Menu.activateOption()

if (Menu.isOpen) {
const activated = Menu.activateOption()
if (activated) Search.close()
return
if (reactive.allPanels) {
return SearchTabs.onTabsSearchEnter(undefined)
}

const actPanel = Sidebar.panelsById[Sidebar.activePanelId]
Expand Down Expand Up @@ -276,6 +285,8 @@ export function selectAll(): void {
if (!Search.reactive.barIsShowed) return
if (Menu.isOpen) return

if (reactive.allPanels) return

const actPanel = Sidebar.panelsById[Sidebar.activePanelId]
if (!actPanel) return

Expand Down Expand Up @@ -356,13 +367,20 @@ export function search(q?: string): void {

// Update query
if (q !== undefined) {
let isGlobal = Settings.state.searchAllPanelsDefault
if (q.startsWith('/')) {
isGlobal = !isGlobal
q = q.slice(1).trimStart()
}

if (q.length < MIN_SEARCH_QUERY_LEN && !regexCJK.test(q)) q = ''
if (query === q) return
if (query === q && reactive.allPanels === isGlobal) return
query = q
lowerCaseQuery = q.toLowerCase()

const v = !!q
if (active !== v) reactive.active = active = v
reactive.allPanels = isGlobal && v
}

if (Menu.isOpen) Menu.close()
Expand All @@ -385,23 +403,29 @@ export function search(q?: string): void {
if (!actPanel) return
let targetPanelId = actPanel.id

if (Utils.isTabsPanel(actPanel)) {
if (Sidebar.subPanelActive) {
if (Sidebar.subPanelType === SubPanelType.Bookmarks && Sidebar.subPanels.bookmarks) {
targetPanelId = Sidebar.subPanels.bookmarks.id
SearchBookmarks.onBookmarksSearch(actPanel, Sidebar.subPanels.bookmarks)
} else if (Sidebar.subPanelType === SubPanelType.History) {
targetPanelId = NOID
SearchHistory.onHistorySearch()
if (reactive.allPanels && query) {
for (const panel of Sidebar.panels) {
if (Utils.isTabsPanel(panel)) SearchTabs.onTabsSearch(panel)
}
} else {
if (Utils.isTabsPanel(actPanel)) {
if (Sidebar.subPanelActive) {
if (Sidebar.subPanelType === SubPanelType.Bookmarks && Sidebar.subPanels.bookmarks) {
targetPanelId = Sidebar.subPanels.bookmarks.id
SearchBookmarks.onBookmarksSearch(actPanel, Sidebar.subPanels.bookmarks)
} else if (Sidebar.subPanelType === SubPanelType.History) {
targetPanelId = NOID
SearchHistory.onHistorySearch()
}
} else {
SearchTabs.onTabsSearch(actPanel)
}
} else {
SearchTabs.onTabsSearch(actPanel)
} else if (Utils.isBookmarksPanel(actPanel)) {
SearchBookmarks.onBookmarksSearch(actPanel, undefined)
} else if (Utils.isHistoryPanel(actPanel)) {
targetPanelId = NOID
SearchHistory.onHistorySearch()
}
} else if (Utils.isBookmarksPanel(actPanel)) {
SearchBookmarks.onBookmarksSearch(actPanel, undefined)
} else if (Utils.isHistoryPanel(actPanel)) {
targetPanelId = NOID
SearchHistory.onHistorySearch()
}

if (query === '') {
Expand Down
36 changes: 36 additions & 0 deletions src/sidebar/components/panel.search.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<template lang="pug">
.SearchPanel
ScrollBox
.search-groups
template(v-for="panel in searchPanels" :key="panel.id")
.search-group(v-if="hasMatches(panel)")
.group-header(:data-color="panel.reactive.color")
img.icon(v-if="!!panel.reactive.iconIMG" :src="panel.reactive.iconIMG")
svg.icon(v-else-if="panel.reactive.iconSVG"): use(:href="'#' + panel.reactive.iconSVG")
.title {{panel.name}}
.group-list
TabComponent(v-for="id in getVisibleTabIds(panel)" :key="id" :tabId="id")
</template>

<script lang="ts" setup>
import { computed } from 'vue'
import * as Sidebar from 'src/services/sidebar.fg'
import * as Utils from 'src/utils'
import ScrollBox from 'src/components/scroll-box.vue'
import TabComponent from './tab.vue'
import type { Panel, TabsPanel } from 'src/types'

const searchPanels = computed(() => {
return Sidebar.panels.filter(p => Utils.isTabsPanel(p))
})

function hasMatches(panel: Panel): boolean {
if (Utils.isTabsPanel(panel)) return (panel.reactive.filteredLen ?? 0) > 0
return false
}

function getVisibleTabIds(panel: Panel): ID[] {
if (!Utils.isTabsPanel(panel)) return []
return panel.reactive.visibleTabIds || []
}
</script>
2 changes: 2 additions & 0 deletions src/sidebar/sidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
:is="getPanelComponent(panel)"
:data-pos="panel.reactive.pos"
:panel="panel")
SearchPanel(v-if="Search.reactive.active && Search.reactive.allPanels")

Transition(name="bottom-bar")
.BottomBar(
Expand Down Expand Up @@ -156,6 +157,7 @@ import PinnedTabsBar from './components/bar.pinned-tabs.vue'
import NotificationsPopup from './components/popup.notifications.vue'
import NavigationBar from './components/bar.navigation.vue'
import WindowsPopup from './components/popup.windows.vue'
import SearchPanel from './components/panel.search.vue'
import TabsPanel from './components/panel.tabs.vue'
import BookmarksPanel from './components/panel.bookmarks.vue'
import HistoryPanel from './components/panel.history.vue'
Expand Down
2 changes: 1 addition & 1 deletion src/styles/sidebar/bar.navigation.styl
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@
opacity: 0
z-index: -1
transform: scale(0, 0)

// Button x position
for i in 0..24
&[data-index=\"{i}\"]
Expand Down
36 changes: 36 additions & 0 deletions src/styles/sidebar/panel.search.styl
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
.SearchPanel
position: absolute
top: 0
left: 0
width: 100%
height: 100%
background-color: var(--frame-bg)
z-index: 20
display: flex
flex-direction: column

.SearchPanel .search-groups
padding: var(--general-margin)
display: flex
flex-direction: column
grid-gap: var(--general-margin)

.SearchPanel .search-group
display: flex
flex-direction: column

.SearchPanel .group-header
display: flex
align-items: center
font-size: rem(14)
font-weight: 600
color: var(--title-fg)
padding: 4px 8px
border-bottom: 1px solid var(--border-color)
margin-bottom: 4px

.SearchPanel .group-header .icon
width: 16px
height: 16px
margin-right: 8px
fill: var(--color, var(--title-fg))
1 change: 1 addition & 0 deletions src/styles/sidebar/sidebar.styl
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ vendors = official
@import './panel.tabs'
@import './panel.bookmarks'
@import './panel.history'
@import './panel.search'
@import './popup.windows'
@import './popup.confirm'
@import './popup.processing-tabs'
Expand Down
1 change: 1 addition & 0 deletions src/types/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export interface SettingsState {
searchPanelSwitch: (typeof SETTINGS_OPTIONS.searchPanelSwitch)[number]
searchTabSwitch: boolean
searchMenuTrig: boolean
searchAllPanelsDefault: boolean
searchBookmarksShortcut: string
searchHistoryShortcut: string
searchInputTimeout: number
Expand Down