Skip to content

Commit e0a5a97

Browse files
author
hoang.tran12
committed
favorite
1 parent 0d53051 commit e0a5a97

File tree

5 files changed

+128
-51
lines changed

5 files changed

+128
-51
lines changed

popup/helpers/storage.js

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,22 +20,42 @@ const createVariableSaver = (key, defaultValue = null) => ({
2020
},
2121
});
2222

23-
const createScriptsSaver = (key) => ({
24-
add: async (script) => {
25-
let current = await localStorage.get(key, []);
26-
current = current.filter((id) => id != script.id); // remove duplicate
27-
current.unshift(script.id); // only save script id
28-
await localStorage.set(key, current);
29-
},
30-
clear: async () => {
23+
const createScriptsSaver = (key) => {
24+
const getIds = async () =>
25+
(await localStorage.get(key, [])).filter(
26+
(savedScriptId) => savedScriptId in allScripts
27+
);
28+
const has = async (script) => {
29+
let current = await getIds();
30+
let exist = current.findIndex((id) => id === script.id) >= 0;
31+
return exist;
32+
};
33+
const add = async (script, addToHead = true) => {
34+
let current = await getIds();
35+
let newList = current.filter((id) => id != script.id); // remove duplicate
36+
if (addToHead) newList.unshift(script.id); // only save script id
37+
else newList.push(script.id);
38+
await localStorage.set(key, newList);
39+
};
40+
const remove = async (script) => {
41+
let current = await getIds();
42+
let newList = current.filter((id) => id !== script.id);
43+
await localStorage.set(key, newList);
44+
console.log("removed ", script);
45+
};
46+
const toggle = async (script) => {
47+
let exist = await has(script);
48+
if (exist) await remove(script);
49+
else await add(script);
50+
};
51+
const clear = async () => {
3152
await localStorage.set(key, []);
32-
},
33-
get: async () => {
34-
return (await localStorage.get(key, []))
35-
.filter((savedScriptId) => savedScriptId in allScripts)
36-
.map((savedScriptId) => allScripts[savedScriptId]);
37-
},
38-
});
53+
};
54+
const get = async () =>
55+
(await getIds()).map((savedScriptId) => allScripts[savedScriptId]);
56+
57+
return { add, remove, has, toggle, clear, getIds, get };
58+
};
3959

4060
export const langSaver = createVariableSaver("useful-scripts-lang");
4161
export const activeTabIdSaver = createVariableSaver(

popup/index.js

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
import config from "../config.js";
2-
import { isTitle, tabs } from "./tabs.js";
2+
import { allScripts } from "../scripts/index.js";
3+
import { isTitle, refreshSpecialTabs, specialTabs, tabs } from "./tabs.js";
34
import { getFlag, t, toggleLang } from "./helpers/lang.js";
45
import { checkBlackWhiteList, runScriptInCurrentTab } from "./helpers/utils.js";
5-
import { activeTabIdSaver, recentScriptsSaver } from "./helpers/storage.js";
6+
import {
7+
activeTabIdSaver,
8+
favoriteScriptsSaver,
9+
recentScriptsSaver,
10+
} from "./helpers/storage.js";
611

712
const tabDiv = document.querySelector("div.tab");
813
const contentDiv = document.querySelector("div.content");
@@ -24,18 +29,31 @@ async function initLanguage() {
2429
}
2530

2631
async function createTabs() {
32+
// prepare tabs
33+
await refreshSpecialTabs();
34+
2735
// clear UI
2836
tabDiv.innerHTML = "";
2937
contentDiv.innerHTML = "";
3038

3139
// make new UI
32-
for (let tab of tabs) {
40+
const allTabs = [...specialTabs, ...tabs];
41+
for (let tab of allTabs) {
3342
// create tab button
3443
const tabBtn = document.createElement("button");
3544
tabBtn.className = "tablinks";
3645
tabBtn.innerHTML = t(tab.name);
3746
tabBtn.type = "button";
3847
tabBtn.setAttribute("content-id", tab.id);
48+
49+
// show scripts count
50+
if (tab.showCount) {
51+
let avaiCount = tab.scripts.filter((script) => !isTitle(script)).length;
52+
let allCount = Object.keys(allScripts).length;
53+
tabBtn.innerHTML += ` (${avaiCount}/${allCount})`;
54+
}
55+
56+
// custom style
3957
if (tab.style && typeof tab.style === "object")
4058
Object.entries(tab.style).forEach(([key, value]) => {
4159
tabBtn.style[key] = value;
@@ -50,7 +68,7 @@ async function createTabs() {
5068

5169
// open tab
5270
let activeTabId = await activeTabIdSaver.get();
53-
activeTabId && openTab(tabs.find((tab) => tab.id === activeTabId));
71+
activeTabId && openTab(allTabs.find((tab) => tab.id === activeTabId));
5472
}
5573

5674
async function openTab(tab) {
@@ -65,22 +83,26 @@ async function openTab(tab) {
6583
.classList.add("active");
6684
}
6785

68-
function createTabContent(tab) {
86+
async function createTabContent(tab) {
6987
// create tab content
7088
const contentContainer = document.createElement("div");
7189
contentContainer.className = "tabcontent";
7290

7391
// create button for scripts in tabcontent
7492
if (!tab.scripts?.length) {
7593
const emptyText = document.createElement("h3");
76-
emptyText.innerText = t({
77-
en: "Nothing here yet...",
78-
vi: "Chưa có gì ở đây hết...",
94+
emptyText.style.padding = "30px 0";
95+
emptyText.style.color = "#19143b";
96+
emptyText.innerHTML = t({
97+
en: `<i class="fa-solid fa-circle-info"></i> Nothing here yet...`,
98+
vi: `<i class="fa-solid fa-circle-info"></i> Chưa có gì ở đây hết...`,
7999
});
80100
contentContainer.appendChild(emptyText);
81101
} else {
102+
const favoriteScriptIds = await favoriteScriptsSaver.getIds();
82103
tab.scripts.forEach((script) => {
83-
contentContainer.appendChild(createScriptButton(script));
104+
let isFavorite = favoriteScriptIds.find((id) => script.id === id);
105+
contentContainer.appendChild(createScriptButton(script, isFavorite));
84106
});
85107
}
86108

@@ -89,7 +111,7 @@ function createTabContent(tab) {
89111
contentDiv.appendChild(contentContainer);
90112
}
91113

92-
function createScriptButton(script) {
114+
function createScriptButton(script, isFavorite = false) {
93115
// Section title
94116
if (isTitle(script)) {
95117
const title = document.createElement("h3");
@@ -144,6 +166,19 @@ function createScriptButton(script) {
144166
title.innerText = t(script.name);
145167
button.appendChild(title);
146168

169+
// add to favorite button
170+
const addFavoriteBtn = document.createElement("i");
171+
addFavoriteBtn.className = isFavorite
172+
? "fa-solid fa-star active"
173+
: "fa-regular fa-star";
174+
addFavoriteBtn.onclick = (e) => {
175+
e.stopPropagation();
176+
e.preventDefault();
177+
178+
favoriteScriptsSaver.toggle(script).then(createTabs);
179+
};
180+
button.appendChild(addFavoriteBtn);
181+
147182
// tooltip
148183
const tooltip = document.createElement("span");
149184
tooltip.classList.add("tooltiptext");

popup/styles/style.css

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ a:hover {
8282
}
8383

8484
.tabcontent {
85-
animation: fadeEffect 1s;
85+
animation: fadeEffect .3s;
8686
}
8787

8888
.section-title {
@@ -122,6 +122,27 @@ a:hover {
122122
transition: all 50ms;
123123
}
124124

125+
.content button i {
126+
opacity: 0;
127+
width: 0;
128+
transition: all .2s;
129+
}
130+
131+
.content button i.active {
132+
color: #0048ad;
133+
}
134+
135+
.content button i:hover {
136+
transform: scale(1.8);
137+
}
138+
139+
.content button:hover i,
140+
.content button i.active {
141+
width: auto;
142+
margin-left: 5px;
143+
opacity: 1;
144+
}
145+
125146
.content button .btn-title {
126147
vertical-align: middle;
127148
}

popup/tabs.js

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,21 @@ import { favoriteScriptsSaver, recentScriptsSaver } from "./helpers/storage.js";
77
const createTitle = (en, vi) => ({ name: { en, vi } });
88
const isTitle = (script) => !script.func && !script.file && !script.link;
99

10+
const specialTabs = [
11+
{
12+
...CATEGORY.recently,
13+
scripts: [],
14+
},
15+
{
16+
...CATEGORY.favorite,
17+
scripts: [],
18+
},
19+
{
20+
...CATEGORY.available,
21+
scripts: [],
22+
},
23+
];
24+
1025
const tabs = [
1126
{
1227
...CATEGORY.search,
@@ -351,30 +366,16 @@ async function getAvailableScriptsInTabs(_tabs) {
351366
return result;
352367
}
353368

354-
tabs.unshift(
355-
{
356-
...CATEGORY.recently,
357-
scripts: await recentScriptsSaver.get(),
358-
},
359-
{
360-
...CATEGORY.favorite,
361-
scripts: await favoriteScriptsSaver.get(),
362-
},
363-
{
364-
...CATEGORY.available,
365-
scripts: await getAvailableScriptsInTabs(tabs),
366-
}
367-
);
369+
async function refreshSpecialTabs() {
370+
// add data to special tabs
371+
let recentTab = specialTabs.find((tab) => tab.id === CATEGORY.recently.id);
372+
if (recentTab) recentTab.scripts = await recentScriptsSaver.get();
368373

369-
// add script count to tab name
370-
tabs.forEach((tab) => {
371-
if (tab.showCount) {
372-
let avaiCount = tab.scripts.filter((script) => !isTitle(script)).length;
373-
let allCount = Object.keys(s).length;
374+
let favoriteTab = specialTabs.find((tab) => tab.id === CATEGORY.favorite.id);
375+
if (favoriteTab) favoriteTab.scripts = await favoriteScriptsSaver.get();
374376

375-
tab.name.vi += ` (${avaiCount}/${allCount})`;
376-
tab.name.en += ` (${avaiCount}/${allCount})`;
377-
}
378-
});
377+
let avaiab = specialTabs.find((tab) => tab.id === CATEGORY.available.id);
378+
if (avaiab) avaiab.scripts = await getAvailableScriptsInTabs(tabs);
379+
}
379380

380-
export { isTitle, tabs };
381+
export { isTitle, refreshSpecialTabs, tabs, specialTabs };

scripts/downDetector.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)