Skip to content

Commit d744666

Browse files
committed
working on sessions
1 parent 66d9092 commit d744666

File tree

3 files changed

+321
-0
lines changed

3 files changed

+321
-0
lines changed
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
<template>
2+
<div class="row q-ma-none q-pa-none" @mouseenter="showIcons = true" @mouseleave="showIcons = false">
3+
<div class="col-2 q-mt-xs" style="text-align: center">
4+
<TabFaviconWidget :preventDragAndDrop="true" :tab="toTab(chromeTab)" width="20px" height="20px" />
5+
</div>
6+
7+
<div
8+
class="col-7 q-mt-sm q-ml-xs text-body2 ellipsis cursor-pointer"
9+
:class="TabService.isCurrentTab(toTab(chromeTab)) ? 'text-bold' : ''"
10+
@click="useNavigationService().browserTabFor(chromeTab.url!)">
11+
{{ chromeTab?.title }}
12+
<q-tooltip class="tooltip" v-if="useFeaturesStore().hasFeature(FeatureIdent.DEV_MODE)">
13+
{{ chromeTab.id }} / {{ chromeTab.url }} / {{ chromeTab.index }}
14+
</q-tooltip>
15+
<q-tooltip class="tooltip" v-else>
16+
{{ chromeTab.url }}
17+
</q-tooltip>
18+
</div>
19+
<div class="col-1 q-mt-xs text-right">
20+
<q-icon v-if="existsInTabset" name="link" :color="existsInCurrentTabset ? 'green' : 'warning'">
21+
<q-tooltip class="tooltip-small" v-if="existsInCurrentTabset"
22+
>Already contained in the current tabset</q-tooltip
23+
>
24+
<q-tooltip class="tooltip-small" v-else>Already contained in a tabset</q-tooltip>
25+
</q-icon>
26+
</div>
27+
<div class="col q-mt-xs text-right">
28+
<template v-if="showIcons">
29+
<q-icon
30+
name="o_add_circle"
31+
:color="alreadyInCurrentTabset ? 'grey' : 'warning'"
32+
class="q-mr-xs"
33+
:class="alreadyInCurrentTabset ? '' : 'cursor-pointer'"
34+
size="xs"
35+
@click="addToCurrentTabset">
36+
</q-icon>
37+
</template>
38+
</div>
39+
</div>
40+
</template>
41+
42+
<script setup lang="ts">
43+
import { uid } from 'quasar'
44+
import { FeatureIdent } from 'src/app/models/FeatureIdent'
45+
import { useCommandExecutor } from 'src/core/services/CommandExecutor'
46+
import { useNavigationService } from 'src/core/services/NavigationService'
47+
import { useFeaturesStore } from 'src/features/stores/featuresStore'
48+
import NavigationService from 'src/services/NavigationService'
49+
import TabService from 'src/services/TabService'
50+
import { CreateTabFromOpenTabsCommand } from 'src/tabsets/commands/CreateTabFromOpenTabs'
51+
import { Tab } from 'src/tabsets/models/Tab'
52+
import { useTabsetService } from 'src/tabsets/services/TabsetService2'
53+
import TabFaviconWidget from 'src/tabsets/widgets/TabFaviconWidget.vue'
54+
import { onMounted, PropType, ref } from 'vue'
55+
56+
const props = defineProps({
57+
chromeTab: { type: Object as PropType<chrome.tabs.Tab>, required: true },
58+
})
59+
60+
const emits = defineEmits(['selectionChanged', 'addedToTabset', 'hasSelectable'])
61+
62+
const showIcons = ref(false)
63+
const alreadyInCurrentTabset = ref(false)
64+
const existsInTabset = ref(false)
65+
const existsInCurrentTabset = ref(false)
66+
67+
onMounted(() => {
68+
if (props.chromeTab?.url) {
69+
existsInTabset.value = useTabsetService().urlExistsInATabset(props.chromeTab.url)
70+
existsInCurrentTabset.value = useTabsetService().urlExistsInCurrentTabset(props.chromeTab.url)
71+
}
72+
})
73+
74+
const closeTab = (tab: chrome.tabs.Tab) => {
75+
NavigationService.closeChromeTab(tab)
76+
}
77+
78+
const addToCurrentTabset = () => {
79+
useCommandExecutor()
80+
.executeFromUi(new CreateTabFromOpenTabsCommand(props.chromeTab as chrome.tabs.Tab, 0))
81+
.then(() => (alreadyInCurrentTabset.value = true))
82+
.then(() => emits('addedToTabset', { tabId: props.chromeTab.id, tabUrl: props.chromeTab.url }))
83+
}
84+
85+
alreadyInCurrentTabset.value = useTabsetService().urlExistsInCurrentTabset(props.chromeTab.url || '')
86+
87+
const toTab = (chromeTab: chrome.tabs.Tab) => new Tab(uid(), chromeTab)
88+
</script>
89+
90+
<style lang="sass" scoped>
91+
92+
.tabBorder
93+
border-radius: 5px 5px 0 0
94+
border: 1px solid $lightgrey
95+
border-bottom: 0
96+
</style>
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
<template>
2+
<!-- SidePanelSessionsListViewer -->
3+
4+
<div class="row q-mt-xs">
5+
<!-- <div class="col-6 q-mt-sm">-->
6+
<!-- <SidePanelTabsetsSelectorWidget :use-as-tabsets-switcher="true" />-->
7+
<!-- </div>-->
8+
<!-- <div class="col-6 text-right">-->
9+
<!-- <template v-if="useWindowsStore().allWindows.size > 1">-->
10+
<!-- Current Window only-->
11+
<!-- <q-checkbox v-model="currentWindowOnly" />-->
12+
<!-- </template>-->
13+
<!-- </div>-->
14+
<!-- <div class="col-11 q-mb-xs">-->
15+
<!-- <q-input dense autofocus ref="filterRef" filled :hint="filterHint()" v-model="filter" label="Filter Tabs">-->
16+
<!-- <template v-slot:append>-->
17+
<!-- <q-icon v-if="filter !== ''" name="clear" class="cursor-pointer" @click="resetFilter" />-->
18+
<!-- </template>-->
19+
<!-- </q-input>-->
20+
<!-- </div>-->
21+
<!-- <div class="col text-right">-->
22+
<!-- <q-icon :name="sortByUrl ? 'undo' : 'sort'" color="primary" class="cursor-pointer" @click="toggleSorting()">-->
23+
<!-- <q-tooltip class="tooltip-small">Toggle Sorting between custom and URL</q-tooltip>-->
24+
<!-- </q-icon>-->
25+
<!-- </div>-->
26+
</div>
27+
28+
<div class="q-pa-none">
29+
<q-list class="rounded-borders">
30+
<q-expansion-item
31+
group="browserWindowSessions"
32+
v-for="session in tabsetsSessions"
33+
expand-separator
34+
:label="'' + session.name"
35+
:caption="'Tabsets Session - ' + session.tabs.length + ' tabs(s)'">
36+
<q-card>
37+
<q-card-section>
38+
<div class="q-ma-none q-mb-md cursor-pointer text-right text-caption" @click="openSession(session)">
39+
open session
40+
</div>
41+
<div v-for="tab in session.tabs" class="q-my-none tabBorder q-mb-xs">
42+
{{ tab.id }}
43+
</div>
44+
</q-card-section>
45+
</q-card>
46+
</q-expansion-item>
47+
<q-expansion-item
48+
group="browserWindowSessions"
49+
v-for="session in recentlyClosedBrowserSessions.filter((s: chrome.sessions.Session) => s.window)"
50+
expand-separator
51+
:label="'' + session.lastModified"
52+
:caption="'Browser Windows Session - ' + session.window?.tabs?.length + ' tabs(s)'">
53+
<q-card>
54+
<q-card-section>
55+
<div
56+
class="q-ma-none q-mb-md cursor-pointer text-right text-caption"
57+
@click="restoreSession(session.window?.sessionId)">
58+
restore session
59+
</div>
60+
<div v-for="tab in session.window?.tabs" class="q-my-none tabBorder q-mb-xs" :style="cardStyle(tab)">
61+
<SimpleBrowserTabCard :chromeTab="tab" />
62+
</div>
63+
</q-card-section>
64+
</q-card>
65+
</q-expansion-item>
66+
</q-list>
67+
</div>
68+
</template>
69+
70+
<script setup lang="ts">
71+
import _ from 'lodash'
72+
import { SidePanelViews } from 'src/app/models/SidePanelViews'
73+
import Analytics from 'src/core/utils/google-analytics'
74+
import SimpleBrowserTabCard from 'src/tabsets/components/helper/SimpleBrowserTabCard.vue'
75+
import { Tabset, TabsetType } from 'src/tabsets/models/Tabset'
76+
import { useTabsetService } from 'src/tabsets/services/TabsetService2'
77+
import { useTabsetsStore } from 'src/tabsets/stores/tabsetsStore'
78+
import { useTabsStore2 } from 'src/tabsets/stores/tabsStore2'
79+
import { useUiStore } from 'src/ui/stores/uiStore'
80+
import { onMounted, ref, watchEffect } from 'vue'
81+
82+
const recentlyClosedBrowserSessions = ref<chrome.sessions.Session[]>([])
83+
const tabsetsSessions = ref<Tabset[]>([])
84+
const useSelection = ref(false)
85+
const userCanSelect = ref(false)
86+
87+
const tabSelection = ref<Set<string>>(new Set<string>())
88+
const tabs = ref<chrome.tabs.Tab[]>([])
89+
90+
onMounted(async () => {
91+
Analytics.firePageViewEvent('SidePanelSessionsListViewer', document.location.href)
92+
recentlyClosedBrowserSessions.value = await chrome.sessions.getRecentlyClosed()
93+
tabsetsSessions.value = [...useTabsetsStore().tabsets.values()].filter((ts: Tabset) => ts.type === TabsetType.SESSION)
94+
})
95+
96+
watchEffect(() => {
97+
tabs.value = useTabsStore2().browserTabs
98+
const filterTerm = useUiStore().toolbarFilterTerm.toLowerCase()
99+
if (filterTerm.length > 0) {
100+
tabs.value = _.filter(
101+
tabs.value,
102+
(t: chrome.tabs.Tab) =>
103+
!!((t.url && t.url?.indexOf(filterTerm) >= 0) || (t.title && t.title.toLowerCase()?.indexOf(filterTerm) >= 0)),
104+
)
105+
}
106+
})
107+
108+
watchEffect(() => {
109+
userCanSelect.value = false
110+
})
111+
112+
const tabSelectionChanged = (a: any) => {
113+
const { tabId, selected } = a
114+
if (selected) {
115+
tabSelection.value.add(tabId)
116+
} else {
117+
tabSelection.value.delete(tabId)
118+
}
119+
}
120+
121+
const openSession = (session: Tabset) => {
122+
useTabsetService().selectTabset(session.id)
123+
useUiStore().sidePanelSetActiveView(SidePanelViews.MAIN)
124+
}
125+
126+
const restoreSession = async (sessionId?: string) => {
127+
const reason = await chrome.sessions.restore(sessionId) //.then((reason: any) => {
128+
console.log('restored session', reason)
129+
recentlyClosedBrowserSessions.value = await chrome.sessions.getRecentlyClosed()
130+
}
131+
132+
const cardStyle = (tab: chrome.tabs.Tab) => {
133+
let background = ''
134+
if (useTabsetService().urlExistsInCurrentTabset(tab.url || '')) {
135+
background = 'background: #efefef'
136+
} else {
137+
// emits('hasSelectable', true)
138+
}
139+
return `${background}`
140+
}
141+
</script>
142+
143+
<style lang="sass" scoped>
144+
145+
.tabBorder
146+
border-radius: 5px 5px 0 0
147+
border: 1px solid $lightgrey
148+
border-bottom: 0
149+
</style>

pages/SidePanelSessionsPage.vue

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<template>
2+
<!-- SidePanelOpenTabsPage -->
3+
<q-page padding style="padding-top: 34px">
4+
<div class="q-ma-none">
5+
<div class="q-ma-none">
6+
<div class="row q-ma-none q-pa-none">
7+
<div class="col-12 q-ma-none q-pa-none q-pt-md">
8+
<SidePanelSessionsListViewer />
9+
</div>
10+
</div>
11+
</div>
12+
</div>
13+
14+
<!-- place QPageSticky at end of page -->
15+
<q-page-sticky expand position="top" class="darkInDarkMode brightInBrightMode">
16+
<ViewToolbarHelper title="Browser Sessions">
17+
<template v-slot:iconsRight>
18+
<div class="q-mt-sm q-ma-none q-qa-none">
19+
<q-btn outline size="xs" label="new session" class="q-mr-md" @click.stop="startSession()" />
20+
</div>
21+
</template>
22+
</ViewToolbarHelper>
23+
</q-page-sticky>
24+
</q-page>
25+
</template>
26+
27+
<script lang="ts" setup>
28+
import ViewToolbarHelper from 'pages/sidepanel/helper/ViewToolbarHelper.vue'
29+
import { useQuasar } from 'quasar'
30+
import BrowserApi from 'src/app/BrowserApi'
31+
import { ExecutionResult } from 'src/core/domain/ExecutionResult'
32+
import { useCommandExecutor } from 'src/core/services/CommandExecutor'
33+
import Analytics from 'src/core/utils/google-analytics'
34+
import { CreateTabsetCommand } from 'src/tabsets/commands/CreateTabsetCommand'
35+
import { RestoreTabsetCommand } from 'src/tabsets/commands/RestoreTabset'
36+
import StartSessionDialog from 'src/tabsets/dialogues/StartSessionDialog.vue'
37+
import { SaveOrReplaceResult } from 'src/tabsets/models/SaveOrReplaceResult'
38+
import { TabsetType } from 'src/tabsets/models/Tabset'
39+
import SidePanelSessionsListViewer from 'src/tabsets/pages/SidePanelSessionsListViewer.vue'
40+
import { useTabsetService } from 'src/tabsets/services/TabsetService2'
41+
import { useTabsetsStore } from 'src/tabsets/stores/tabsetsStore'
42+
import { useTabsStore2 } from 'src/tabsets/stores/tabsStore2'
43+
import { onMounted } from 'vue'
44+
45+
const $q = useQuasar()
46+
47+
onMounted(() => {
48+
Analytics.firePageViewEvent('SidePanelSessionsPage', document.location.href)
49+
})
50+
51+
const startSession = () => {
52+
$q.dialog({
53+
component: StartSessionDialog,
54+
}).onOk((callback: { oldSessionName: string; collection: string }) => {
55+
console.log('callback', callback)
56+
const tabsToUse = useTabsStore2().browserTabs
57+
useCommandExecutor()
58+
.execute(new CreateTabsetCommand(callback.oldSessionName, tabsToUse))
59+
.then((res: ExecutionResult<SaveOrReplaceResult>) => {
60+
console.log('res', res.result.tabset)
61+
const ts = res.result.tabset
62+
ts.type = TabsetType.SESSION
63+
useTabsetsStore().saveTabset(ts)
64+
BrowserApi.closeAllTabs(false)
65+
})
66+
.then(() => {
67+
const tabsetId = callback.collection['value' as keyof object]
68+
//useCommandExecutor().executeFromUi(new CreateTabsetCommand(callback['sessionName' as keyof object], []))
69+
if (tabsetId) {
70+
useTabsetService().selectTabset(tabsetId)
71+
useCommandExecutor().execute(new RestoreTabsetCommand(tabsetId, undefined, false))
72+
}
73+
})
74+
})
75+
}
76+
</script>

0 commit comments

Comments
 (0)