Skip to content

Commit 1281f8b

Browse files
wip
1 parent ea89345 commit 1281f8b

File tree

11 files changed

+314
-31
lines changed

11 files changed

+314
-31
lines changed

src/Options.vue

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
<CloseIcon />
1616
</label>
1717

18-
<a class="btn btn-ghost text-xl">
18+
<h1 class="text-xl font-semibold ml-4">
1919
{{ currentContent.title }}
20-
</a>
20+
</h1>
2121
</div>
2222

2323
<div class="navbar-end mr-2">
@@ -167,6 +167,10 @@ onMounted(async () => {
167167
menuStore.setCurrentMenuItem(currentContent.value);
168168
169169
await rulesStore.init();
170+
171+
emitter.on(GLOBAL_EVENTS.NAVIGATE_TO_SETTINGS, () => {
172+
onMenuClicked(sectionItems.find((item) => item.component === 'SettingsPane')!);
173+
});
170174
});
171175
</script>
172176

src/common/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export const GLOBAL_EVENTS = {
5353
CLOSE_ADD_GROUP_MODAL: 'CLOSE_ADD_GROUP_MODAL',
5454
GLOBAL_KEY_SAVE: 'GLOBAL_KEY_SAVE',
5555
SHOW_TOAST: 'SHOW_TOAST',
56+
NAVIGATE_TO_SETTINGS: 'NAVIGATE_TO_SETTINGS',
5657
};
5758

5859
export type RuleModalParams = {
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<template>
2+
<div class="mt-6 text-center">
3+
<transition name="fade" mode="out-in">
4+
<p :key="currentTip.id" class="text-xs text-base-content/50">
5+
{{ currentTip.icon }} {{ currentTip.text }}
6+
<a
7+
v-if="currentTip.linkText"
8+
class="link link-primary hover:link-accent"
9+
@click="handleClick(currentTip.action)"
10+
>
11+
{{ currentTip.linkText }}
12+
</a>
13+
{{ currentTip.textAfter }}
14+
</p>
15+
</transition>
16+
</div>
17+
</template>
18+
19+
<script lang="ts" setup>
20+
import { ref, onMounted, onUnmounted, inject } from 'vue';
21+
import { GLOBAL_EVENTS } from '../../common/types.ts';
22+
23+
export interface Tip {
24+
id: number;
25+
icon: string;
26+
text: string;
27+
linkText?: string;
28+
textAfter?: string;
29+
action?: string;
30+
}
31+
32+
export interface Props {
33+
tips: Tip[];
34+
interval?: number;
35+
}
36+
37+
const props = withDefaults(defineProps<Props>(), {
38+
interval: 8000, // 8 seconds by default
39+
});
40+
41+
const emitter: any = inject('emitter');
42+
const currentIndex = ref(0);
43+
const currentTip = ref(props.tips[0]);
44+
let intervalId: number | null = null;
45+
46+
const nextTip = () => {
47+
if (props.tips.length <= 1) return;
48+
49+
currentIndex.value = (currentIndex.value + 1) % props.tips.length;
50+
currentTip.value = props.tips[currentIndex.value];
51+
};
52+
53+
const handleClick = (action?: string) => {
54+
if (!action) return;
55+
56+
if (action === 'navigate-settings') {
57+
emitter.emit(GLOBAL_EVENTS.NAVIGATE_TO_SETTINGS);
58+
}
59+
// Add more actions here as needed
60+
};
61+
62+
onMounted(() => {
63+
if (props.tips.length > 1) {
64+
intervalId = setInterval(nextTip, props.interval);
65+
}
66+
});
67+
68+
onUnmounted(() => {
69+
if (intervalId) {
70+
clearInterval(intervalId);
71+
}
72+
});
73+
</script>
74+
75+
<style scoped>
76+
.fade-enter-active,
77+
.fade-leave-active {
78+
transition: opacity 0.5s ease;
79+
}
80+
81+
.fade-enter-from,
82+
.fade-leave-to {
83+
opacity: 0;
84+
}
85+
</style>

src/components/icons/GripIcon.vue

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<template>
2+
<svg
3+
class="w-6 h-6"
4+
fill="none"
5+
stroke="currentColor"
6+
stroke-width="1.5"
7+
viewBox="0 0 24 24"
8+
xmlns="http://www.w3.org/2000/svg"
9+
>
10+
<path
11+
d="M8.25 15L12 18.75 15.75 15m-7.5-6L12 5.25 15.75 9"
12+
stroke-linecap="round"
13+
stroke-linejoin="round"
14+
/>
15+
</svg>
16+
</template>

src/components/options/center/sections/HelpPane.vue

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,10 @@
4949

5050
<h3 class="font-bold">URL fragment</h3>
5151
<p>
52-
This is the key of your rule. It will determine if your rule will be applied or not. You
53-
want to catch GMail? You can set your rule with "Contains" detection and "mail.google.com"
54-
URL fragment. Another solution could be to set "Starts with" detection and
55-
"https://mail.google.com". Try any combination to achieve what you want.
52+
This is the key of your rule. It will determine if your rule will be applied or not. For
53+
example, to catch GitHub repositories, you can set your rule with "Contains" detection and
54+
"github.com" URL fragment. Another solution could be to set "Starts with" detection and
55+
"https://github.com". Try any combination to achieve what you want.
5656
</p>
5757
<p class="text-accent">
5858
After defining the core of your rule you can select some actions listed below.
@@ -77,15 +77,13 @@
7777
<p>You can select an icon provided by the extension.</p>
7878
<p>
7979
Otherwise, you can define an icon URL in the input like
80-
"https://www.google.com/favicon.ico".
80+
"https://example.com/favicon.ico".
8181
</p>
82-
<p>In case you want to define a local icon from your computer, you have 2 options:</p>
82+
<p>For local icons from your computer, you have multiple options:</p>
8383
<ul class="list-disc ml-3">
84-
<li>upload your icon somewhere like imgur.com and paste the direct link</li>
85-
<li>
86-
go to <a href="https://ezgif.com/image-to-datauri" target="_blank" class="link">ezgif.com</a> and upload your icon, then copy the generated Data URI and paste it.
87-
This is your icon transformed in the Data URI format
88-
</li>
84+
<li><strong>Paste directly</strong>: Copy an image (screenshot, file, etc.) and paste it directly into the "Custom Icon" field - it will be automatically converted to base64!</li>
85+
<li>Upload your icon somewhere like imgur.com and paste the direct link</li>
86+
<li>Use a service to convert your icon to Data URI format manually</li>
8987
</ul>
9088

9189
<h3 class="font-bold">Group</h3>
@@ -109,8 +107,8 @@
109107
the original tab after closing the duplicate one.
110108
</p>
111109
<p>
112-
Scenario: create a rule based on GMail with unique action. Open GMail, open another GMail,
113-
the last one will be closed.
110+
Scenario: create a rule based on your email service with unique action. Open your email,
111+
open another tab with the same email, the last one will be closed.
114112
</p>
115113

116114
<h3 class="font-bold">Muted</h3>
@@ -124,7 +122,7 @@
124122
<p>
125123
An advanced usage, enter a regular expression to identify some title parts and use them
126124
inside the title itself, this is useful to reorder words or exclude some parts of the
127-
title, like [a-z]*@gmail.com and use @0 in the title input to inject the variable.
125+
title, like [a-z]*@example.com and use @0 in the title input to inject the variable.
128126
</p>
129127

130128
<h3 class="font-bold">URL matcher</h3>
Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
<template>
2-
<div class="hero min-h-screen bg-base-200">
3-
<div class="hero-content text-center">
4-
<div class="max-w-md">
2+
<div class="hero min-h-screen bg-base-200 relative overflow-hidden">
3+
<div class="absolute inset-0 opacity-10">
4+
<div class="pattern-background"></div>
5+
</div>
6+
<div class="hero-content text-center relative z-10">
7+
<div class="max-w-lg">
58
<h1 class="text-5xl font-bold">Hello there</h1>
6-
<p class="py-6">
7-
There is no group yet! Hit the following button to create your first group.
9+
<p class="py-6 text-lg">There is no group yet!</p>
10+
<p class="pb-6 text-base opacity-80">
11+
Groups allow you to organize your tabs visually in your browser. Create a group and then
12+
assign it to a rule to automatically group matching tabs together.
813
</p>
914
<button class="btn btn-primary" @click="onGetStartedClicked">Create my first Group</button>
15+
16+
<Disclaimer class="mt-8" :tips="groupsTips" />
1017
</div>
1118
</div>
1219
</div>
@@ -15,12 +22,45 @@
1522
<script lang="ts" setup>
1623
import { inject } from 'vue';
1724
import { GLOBAL_EVENTS } from '../../../../../common/types.ts';
25+
import Disclaimer from '../../../../global/Disclaimer.vue';
1826
1927
const emitter: any = inject('emitter');
2028
2129
const onGetStartedClicked = () => {
2230
emitter.emit(GLOBAL_EVENTS.OPEN_ADD_GROUP_MODAL);
2331
};
32+
33+
const groupsTips = [
34+
{
35+
id: 1,
36+
icon: '💡',
37+
text: 'You can backup and import your groups in',
38+
linkText: 'Settings',
39+
action: 'navigate-settings',
40+
},
41+
{
42+
id: 2,
43+
icon: '🎨',
44+
text: 'Groups help visually organize tabs in your browser',
45+
},
46+
{
47+
id: 3,
48+
icon: '🔗',
49+
text: 'Assign groups to rules to automatically organize matching tabs',
50+
},
51+
{
52+
id: 4,
53+
icon: '📌',
54+
text: 'Pinned tabs cannot be grouped - unpin them first',
55+
},
56+
];
2457
</script>
2558

26-
<style scoped></style>
59+
<style scoped>
60+
.pattern-background {
61+
width: 100%;
62+
height: 100%;
63+
background-image: radial-gradient(circle, currentColor 1px, transparent 1px);
64+
background-size: 32px 32px;
65+
}
66+
</style>

src/components/options/center/sections/TabGroupsPane.vue

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
<TableGroups :groups="rulesStore.groups" />
99
</div>
1010
</div>
11+
12+
<Disclaimer :tips="groupsTips" />
1113
</div>
1214

1315
<dialog ref="addGroupModal" class="modal">
@@ -25,6 +27,7 @@ import { inject, onMounted, onUnmounted, ref } from 'vue';
2527
import { GLOBAL_EVENTS, GroupModalParams } from '../../../../common/types.ts';
2628
import GroupForm from './TabGroups/GroupForm.vue';
2729
import TableGroups from './TabGroups/TableGroups.vue';
30+
import Disclaimer from '../../../global/Disclaimer.vue';
2831
2932
const rulesStore = useRulesStore();
3033
rulesStore.init();
@@ -34,6 +37,31 @@ const isGroupFormModalOpened = ref(false);
3437
3538
const emitter: any = inject('emitter');
3639
40+
const groupsTips = [
41+
{
42+
id: 1,
43+
icon: '💡',
44+
text: 'You can backup and import your groups in',
45+
linkText: 'Settings',
46+
action: 'navigate-settings',
47+
},
48+
{
49+
id: 2,
50+
icon: '🎨',
51+
text: 'Groups help visually organize tabs in your browser',
52+
},
53+
{
54+
id: 3,
55+
icon: '🔗',
56+
text: 'Assign groups to rules to automatically organize matching tabs',
57+
},
58+
{
59+
id: 4,
60+
icon: '📌',
61+
text: 'Pinned tabs cannot be grouped - unpin them first',
62+
},
63+
];
64+
3765
onMounted(() => {
3866
emitter.on(GLOBAL_EVENTS.OPEN_ADD_GROUP_MODAL, openAddGroupModal);
3967
emitter.on(GLOBAL_EVENTS.CLOSE_ADD_GROUP_MODAL, closeAddGroupModal);
Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
<template>
2-
<div class="hero min-h-screen bg-base-200">
3-
<div class="hero-content text-center">
4-
<div class="max-w-md">
2+
<div class="hero min-h-screen bg-base-200 relative overflow-hidden">
3+
<div class="absolute inset-0 opacity-10">
4+
<div class="pattern-background"></div>
5+
</div>
6+
<div class="hero-content text-center relative z-10">
7+
<div class="max-w-lg">
58
<h1 class="text-5xl font-bold">Hello there</h1>
6-
<p class="py-6">
7-
There is no rule yet! Hit the following button to create your first rule.
9+
<p class="py-6 text-lg">There is no rule yet!</p>
10+
<p class="pb-6 text-base opacity-80">
11+
Rules allow you to automatically customize tabs based on their URL. You can change titles,
12+
icons, pin tabs, group them, and much more when they match your criteria.
813
</p>
914
<button class="btn btn-primary" @click="onGetStartedClicked">Create my first Rule</button>
15+
16+
<Disclaimer class="mt-8" :tips="rulesTips" />
1017
</div>
1118
</div>
1219
</div>
@@ -15,12 +22,45 @@
1522
<script lang="ts" setup>
1623
import { inject } from 'vue';
1724
import { GLOBAL_EVENTS } from '../../../../../common/types.ts';
25+
import Disclaimer from '../../../../global/Disclaimer.vue';
1826
1927
const emitter: any = inject('emitter');
2028
2129
const onGetStartedClicked = () => {
2230
emitter.emit(GLOBAL_EVENTS.OPEN_ADD_RULE_MODAL);
2331
};
32+
33+
const rulesTips = [
34+
{
35+
id: 1,
36+
icon: '💡',
37+
text: 'You can backup and import your rules in',
38+
linkText: 'Settings',
39+
action: 'navigate-settings',
40+
},
41+
{
42+
id: 2,
43+
icon: '🎯',
44+
text: 'Rules are applied in order - drag to reorder them',
45+
},
46+
{
47+
id: 3,
48+
icon: '',
49+
text: 'Use RegEx detection for advanced URL matching',
50+
},
51+
{
52+
id: 4,
53+
icon: '🔍',
54+
text: 'Right-click any page to quickly rename its tab',
55+
},
56+
];
2457
</script>
2558

26-
<style scoped></style>
59+
<style scoped>
60+
.pattern-background {
61+
width: 100%;
62+
height: 100%;
63+
background-image: radial-gradient(circle, currentColor 1px, transparent 1px);
64+
background-size: 32px 32px;
65+
}
66+
</style>

0 commit comments

Comments
 (0)