Skip to content

Commit 44a02a5

Browse files
committed
safepoint
1 parent fe7a25b commit 44a02a5

31 files changed

+1476
-453
lines changed
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
<template>
2+
<!-- SpecialUrlAddToTabsetComponent -->
3+
<!-- {{ handler.actions(currentTabsetId, { tabset: props.tabset, level: props.level }) }}-->
4+
<template
5+
v-if="handler.actions(currentTabsetId, { tabset: props.tabset, level: 'root' }).length == 0 && defaultAction">
6+
<q-btn
7+
padding="xs"
8+
fab-mini
9+
unelevated
10+
@click.stop="emits('buttonClicked', new ActionHandlerButtonClickedHolder(handler, defaultAction))"
11+
class="q-ma-none q-px-sm q-py-none"
12+
:icon="defaultAction.icon"
13+
:class="{ shakeWithColor: animateAddtabButton, 'cursor-pointer': !alreadyInTabset }"
14+
:color="alreadyInTabset ? 'grey-5' : containedInTsCount > 0 ? 'primary' : 'warning'"
15+
size="12px"
16+
data-testid="saveInTabsetBtn">
17+
<!-- <div>{{ defaultAction.label }}</div>-->
18+
<!-- <q-icon right class="q-ma-none q-pa-none" size="2em" name="o_south" />-->
19+
</q-btn>
20+
<q-tooltip class="tooltip-small" v-if="alreadyInTabset"> Already in current tabset</q-tooltip>
21+
<q-tooltip class="tooltip-small" v-else-if="containedInTsCount > 0">
22+
{{ tooltipAlreadyInOtherTabsets(props.tabset!.name) }}
23+
</q-tooltip>
24+
<q-tooltip class="tooltip-small" v-else>
25+
Add current Tab to '{{ tabsetNameOrChain(props.tabset as Tabset) }}'...
26+
</q-tooltip>
27+
</template>
28+
29+
<!-- SpecialUrlAddToTabsetComponent handlerDefaultAction -->
30+
<template v-else-if="showExtraMenuItems()">
31+
<!-- :disable="!handler.actions()[0]!.active(props.currentChromeTab)"-->
32+
<q-btn
33+
fab-mini
34+
glossy
35+
padding="xs"
36+
rounded
37+
@click.stop="emits('buttonClicked', new ActionHandlerButtonClickedHolder(handler, defaultAction))"
38+
class="q-ma-none q-pa-none"
39+
:icon="defaultAction?.icon"
40+
:class="{ shakeWithColor: animateAddtabButton, 'cursor-pointer': !alreadyInTabset }"
41+
:color="alreadyInTabset ? 'grey-5' : containedInTsCount > 0 ? 'primary' : 'warning'"
42+
data-testid="saveInTabsetBtn">
43+
<!-- <div>{{ defaultAction.label }}</div>-->
44+
<!-- <q-icon right class="q-ma-none q-pa-none" size="2em" name="o_south" />-->
45+
<q-tooltip class="tooltip-small" v-if="alreadyInTabset"> Already in current tabset</q-tooltip>
46+
<q-tooltip class="tooltip-small" v-else-if="containedInTsCount > 0">
47+
{{ tooltipAlreadyInOtherTabsets(props.tabset!.name) }}
48+
</q-tooltip>
49+
<q-tooltip class="tooltip-small" v-else>
50+
Add current Tab to '{{ tabsetNameOrChain(props.tabset as Tabset) }}'...
51+
</q-tooltip>
52+
</q-btn>
53+
54+
<transition appear>
55+
<span>
56+
<q-btn flat icon="more_vert" text-color="primary" class="cursor-pointer q-ma-none q-pa-none" size="md" />
57+
<q-menu :offset="[0, 0]" @click.stop="">
58+
<q-list dense style="min-width: 200px">
59+
<template v-for="l in handler.actions(currentTabsetId, { tabset: props.tabset, level: 'root' })">
60+
<template v-if="'context' in l">
61+
<component
62+
:key="l.component.name"
63+
:is="l.component"
64+
:tabset="props.tabset"
65+
:folder="props.folder"
66+
:level="'root'"
67+
:context="'context' in l ? l.context : {}" />
68+
</template>
69+
<template v-else>
70+
<component :key="l.name" :is="l" :tabset="props.tabset" :folder="props.folder" :level="'root'" />
71+
</template>
72+
</template>
73+
</q-list>
74+
</q-menu>
75+
</span>
76+
</transition>
77+
</template>
78+
</template>
79+
80+
<script lang="ts" setup>
81+
import { useQuasar } from 'quasar'
82+
import { useActionHandlers } from 'src/tabsets/actionHandling/ActionHandlers'
83+
import { AddUrlToTabsetHandler } from 'src/tabsets/actionHandling/AddUrlToTabsetHandler'
84+
import { NoopAddUrlToTabsetHandler } from 'src/tabsets/actionHandling/handler/NoopAddUrlToTabsetHandler'
85+
import { ActionContext } from 'src/tabsets/actionHandling/model/ActionContext'
86+
import { ActionHandlerButtonClickedHolder } from 'src/tabsets/actionHandling/model/ActionHandlerButtonClickedHolder'
87+
import { useTabsetService } from 'src/tabsets/services/TabsetService2'
88+
import { useTabsetsStore } from 'src/tabsets/stores/tabsetsStore'
89+
import { useUiStore } from 'src/ui/stores/uiStore'
90+
import { ref, watchEffect } from 'vue'
91+
import { Tabset } from '../models/Tabset'
92+
93+
const props = defineProps<{
94+
currentChromeTab: chrome.tabs.Tab
95+
tabset: Tabset
96+
folder?: Tabset
97+
}>()
98+
99+
const emits = defineEmits(['buttonClicked', 'asNewFile', 'extraSpaceNeeded'])
100+
101+
const $q = useQuasar()
102+
103+
const { getHandler } = useActionHandlers($q)
104+
105+
const handler = ref<AddUrlToTabsetHandler>(new NoopAddUrlToTabsetHandler())
106+
const defaultAction = ref<ActionContext | undefined>(undefined)
107+
const containedInTsCount = ref(0)
108+
const animateAddtabButton = ref(false)
109+
const currentTabsetId = ref<string | undefined>(undefined)
110+
const alreadyInTabset = ref(false)
111+
//const extraMenuItems = ref(false)
112+
113+
watchEffect(() => {
114+
useTabsetsStore()
115+
.getCurrentTabsetId()
116+
.then((tsId: string | undefined) => (currentTabsetId.value = tsId))
117+
})
118+
119+
const showExtraMenuItems = () => {
120+
const res: boolean =
121+
handler.value.actions(currentTabsetId.value, { tabset: props.tabset, level: 'root' }).length > 0 &&
122+
defaultAction.value !== undefined
123+
emits('extraSpaceNeeded', res)
124+
return res
125+
}
126+
127+
watchEffect(() => {
128+
handler.value = getHandler(props.currentChromeTab.url, props.folder)
129+
defaultAction.value = handler.value.defaultAction()
130+
showExtraMenuItems()
131+
})
132+
133+
watchEffect(() => {
134+
containedInTsCount.value = useTabsetService().tabsetsFor(props.currentChromeTab.url!).length
135+
})
136+
137+
watchEffect(() => {
138+
animateAddtabButton.value = useUiStore().animateAddtabButton
139+
})
140+
141+
watchEffect(() => {
142+
alreadyInTabset.value = useTabsetService().urlExistsInCurrentTabset(props.currentChromeTab.url)
143+
})
144+
145+
const activeFolderNameFor = (ts: Tabset, activeFolder: string) => {
146+
const folder = useTabsetsStore().getActiveFolder(ts, activeFolder)
147+
return folder ? folder.name : ts.name
148+
}
149+
150+
const tabsetNameOrChain = (tabset: Tabset) => {
151+
return tabset.folderActive ? activeFolderNameFor(tabset, tabset.folderActive) : tabset.name
152+
}
153+
154+
const tooltipAlreadyInOtherTabsets = (tabsetName: string) =>
155+
`Already contained in ${containedInTsCount.value} other tabsets. Click to add here as well.`
156+
</script>
157+
158+
<style>
159+
.q-btn-dropdown--simple * + .q-btn-dropdown__arrow {
160+
margin-left: 0;
161+
border: 1px solid red;
162+
}
163+
164+
.q-btn-dropdown--split .q-btn-dropdown__arrow-container {
165+
padding: 0;
166+
}
167+
</style>

actionHandling/SpecialUrlAddToTabsetComponent.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44
<template
55
v-if="handler.actions(currentTabsetId, { tabset: props.tabset, level: props.level }).length == 0 && defaultAction">
66
<q-btn
7-
outline
87
@click.stop="emits('buttonClicked', new ActionHandlerButtonClickedHolder(handler, defaultAction))"
98
class="q-ma-none q-px-sm q-py-none"
9+
:icon="defaultAction.icon"
1010
:class="{ shakeWithColor: animateAddtabButton, 'cursor-pointer': !alreadyInTabset }"
11-
:color="alreadyInTabset ? 'grey-5' : containedInTsCount > 0 ? 'positive' : ''"
11+
:color="alreadyInTabset ? 'grey-5' : containedInTsCount > 0 ? 'primary' : 'secondary'"
1212
:size="props.level === 'root' ? 'sm' : 'xs'"
1313
data-testid="saveInTabsetBtn">
14-
<div>{{ defaultAction.label }}</div>
14+
<!-- <div>{{ defaultAction.label }}</div>-->
1515
<!-- <q-icon right class="q-ma-none q-pa-none" size="2em" name="o_south" />-->
1616
</q-btn>
1717
<q-tooltip class="tooltip-small" v-if="alreadyInTabset">

actionHandling/handler/DefaultActions.ts

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,12 @@
11
import { LocalStorage } from 'quasar'
2-
import { FeatureIdent } from 'src/app/models/FeatureIdent'
32
import { useContentStore } from 'src/content/stores/contentStore'
4-
import { useFeaturesStore } from 'src/features/stores/featuresStore'
53
import { ComponentWithContext } from 'src/tabsets/actionHandling/AddUrlToTabsetHandler'
6-
import ArchiveTabsetAction from 'src/tabsets/actions/ArchiveTabsetAction.vue'
74
import ConvertToCollectionAction from 'src/tabsets/actions/ConvertToCollectionAction.vue'
8-
import CreateNoteAction from 'src/tabsets/actions/CreateNoteAction.vue'
95
import DeleteFolderAction from 'src/tabsets/actions/DeleteFolderAction.vue'
10-
import EditFolderAction from 'src/tabsets/actions/EditFolderAction.vue'
11-
import ExportTabsetAction from 'src/tabsets/actions/ExportTabsetAction.vue'
126
import { ActionProps } from 'src/tabsets/actions/models/ActionProps'
137
import NewTabAction from 'src/tabsets/actions/NewTabAction.vue'
148
import OpenTabsetAction from 'src/tabsets/actions/OpenTabsetAction.vue'
15-
import { Tabset, TabsetStatus, TabsetType } from 'src/tabsets/models/Tabset'
9+
import { Tabset, TabsetType } from 'src/tabsets/models/Tabset'
1610
import { useTabsetService } from 'src/tabsets/services/TabsetService2'
1711
import { Component } from 'vue'
1812

@@ -22,30 +16,30 @@ export class DefaultActions {
2216
actionProps: ActionProps,
2317
): (ComponentWithContext | Component)[] {
2418
const actions: (ComponentWithContext | Component)[] = []
25-
if (actionProps.level === 'folder') {
26-
actions.push(EditFolderAction)
27-
}
19+
// if (actionProps.level === 'folder') {
20+
// actions.push(EditFolderAction)
21+
// }
2822

29-
if (useFeaturesStore().hasFeature(FeatureIdent.NOTES)) {
30-
actions.push(CreateNoteAction)
31-
}
23+
// if (useFeaturesStore().hasFeature(FeatureIdent.NOTES)) {
24+
// actions.push(CreateNoteAction)
25+
// }
3226

33-
if (
34-
currentTabset &&
35-
useFeaturesStore().hasFeature(FeatureIdent.ARCHIVE_TABSET) &&
36-
currentTabset.status === TabsetStatus.DEFAULT
37-
) {
38-
actions.push(ArchiveTabsetAction)
39-
}
27+
// if (
28+
// currentTabset &&
29+
// useFeaturesStore().hasFeature(FeatureIdent.ARCHIVE_TABSET) &&
30+
// currentTabset.status === TabsetStatus.DEFAULT
31+
// ) {
32+
// actions.push(ArchiveTabsetAction)
33+
// }
4034
if (currentTabset && currentTabset.type === TabsetType.SESSION) {
4135
actions.push(ConvertToCollectionAction)
4236
}
4337

4438
// actions.push(OpenAllInMenuAction)
4539

46-
if (useFeaturesStore().hasFeature(FeatureIdent.DEV_MODE)) {
47-
actions.push(ExportTabsetAction)
48-
}
40+
// if (useFeaturesStore().hasFeature(FeatureIdent.DEV_MODE)) {
41+
// actions.push(ExportTabsetAction)
42+
// }
4943

5044
if (LocalStorage.getItem('ui.newtab.installed') && actionProps.level === 'root') {
5145
actions.push(NewTabAction)

actionHandling/handler/DefaultAddUrlToTabsetHandler.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export class DefaultAddUrlToTabsetHandler implements AddUrlToTabsetHandler {
3030

3131
defaultAction(): ActionContext {
3232
const limitReached = useAuthStore().limitExceeded('TABS', useTabsetsStore().allTabsCount + 1).exceeded
33-
return new ActionContext('Add Tab')
33+
return new ActionContext('Add Tab', 'sym_o_add')
3434
.setColor(() => {
3535
const tabUrl = useContentStore().getCurrentTabUrl
3636
if (tabUrl) {

actionHandling/handler/RssFolderHandler.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export class RssFolderHandler implements AddUrlToTabsetHandler {
3333
}
3434

3535
defaultAction(): ActionContext {
36-
return new ActionContext('(Re-)Load').onClicked(this.clicked)
36+
return new ActionContext('(Re-)Load', 'o_refresh').onClicked(this.clicked)
3737
}
3838

3939
actions(currentTabsetId: string | undefined, actionProps: ActionProps): Component[] {

actions/SearchAction.vue

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<template>
2+
<template v-if="props.level === 'root'">
3+
<q-separator inset />
4+
<ContextMenuItem v-close-popup @was-clicked="clicked()" icon="search" color="primary" label="Search" />
5+
</template>
6+
</template>
7+
<script setup lang="ts">
8+
import ContextMenuItem from 'src/core/components/helper/ContextMenuItem.vue'
9+
import { ActionProps } from 'src/tabsets/actions/models/ActionProps'
10+
import { useUiStore } from 'src/ui/stores/uiStore'
11+
12+
const props = defineProps<ActionProps>()
13+
const emits = defineEmits(['clicked'])
14+
const clicked = () => {
15+
useUiStore().setQuickAccess('search', true)
16+
emits('clicked')
17+
}
18+
</script>

commands/UpdateTabCommand.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,18 @@ import Analytics from 'src/core/utils/google-analytics'
44
import { useSearchStore } from 'src/search/stores/searchStore'
55
import { Tab, UrlExtension } from 'src/tabsets/models/Tab'
66
import TabsetService from 'src/tabsets/services/TabsetService'
7+
import { ListDetailLevel } from 'src/ui/stores/uiStore'
78

89
class UndoCommand implements Command<any> {
910
constructor(
1011
public tab: Tab,
1112
public oldUrl: string,
13+
public oldDetails: ListDetailLevel,
1214
) {}
1315

1416
execute(): Promise<ExecutionResult<any>> {
1517
console.info(this.tab, `reverting changed tab url to ${this.oldUrl}`)
18+
this.tab.details = this.oldDetails
1619
return TabsetService.setUrl(this.tab, this.oldUrl)
1720
.then((res) => {
1821
Analytics.fireEvent('tabset_tab_updated', {})
@@ -21,7 +24,7 @@ class UndoCommand implements Command<any> {
2124
}
2225
return res
2326
})
24-
.then((res) => new ExecutionResult(res, "Tab's URL change was undone"))
27+
.then((res) => new ExecutionResult(res, 'Tab change was undone'))
2528
}
2629
}
2730

@@ -31,13 +34,16 @@ export class UpdateTabCommand implements Command<any> {
3134
public newUrl: string,
3235
public newName: string,
3336
public newDesc: string,
37+
public details: ListDetailLevel = 'DEFAULT',
3438
public placeholders: string[] = [],
3539
public placeholderValues: Map<string, string> = new Map(),
3640
public extension: UrlExtension = UrlExtension.HTML,
3741
) {}
3842

3943
async execute(): Promise<ExecutionResult<string>> {
4044
const oldUrl = this.tab.url || ''
45+
const oldDetails = this.tab.details
46+
this.tab.details = this.details
4147
await TabsetService.setCustomTitle(this.tab, this.newName, this.newDesc)
4248
return TabsetService.setUrl(this.tab, this.newUrl, this.placeholders, this.placeholderValues, this.extension)
4349
.then((ignored) => {
@@ -47,7 +53,11 @@ export class UpdateTabCommand implements Command<any> {
4753
})
4854
.then((ignored) =>
4955
Promise.resolve(
50-
new ExecutionResult(this.newUrl, 'Tab updated', new Map([['Undo', new UndoCommand(this.tab, oldUrl)]])),
56+
new ExecutionResult(
57+
this.newUrl,
58+
'Tab updated',
59+
new Map([['Undo', new UndoCommand(this.tab, oldUrl, oldDetails)]]),
60+
),
5161
),
5262
)
5363
.catch((err) => Promise.reject(err))

dialogues/DeleteSubfolderDialog.vue

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,12 @@
1111
</div>
1212
</q-card-section>
1313
<q-card-actions align="right">
14-
<DialogButton label="Cancel" color="accent" v-close-popup />
14+
<DialogButton label="Cancel" v-close-popup />
1515
<DialogButton
1616
label="Delete"
17-
type="submit"
18-
:autofocus="true"
17+
:default-action="true"
1918
@keyup.enter="deleteFolder()"
20-
@wasClicked="deleteFolder()"
21-
v-close-popup />
19+
@wasClicked="deleteFolder()" />
2220
</q-card-actions>
2321
</q-card>
2422
</div>

0 commit comments

Comments
 (0)