Skip to content

Commit dacd9fe

Browse files
committed
Fix link group duplicates when upgrading
1 parent 04aa2f4 commit dacd9fe

File tree

7 files changed

+221
-54
lines changed

7 files changed

+221
-54
lines changed

src/scripts/imports.ts

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export function filterImports(current: Sync, target: Partial<Sync>) {
1616
let newcurrent = current
1717

1818
// Prepare imported data compatibility
19+
newtarget = convertOldCssSelectors(newtarget) // all
1920

2021
newtarget = booleanSearchbarToObject(newtarget) // 9.0
2122
newtarget = linkListToFlatObjects(newtarget) // 13.0
@@ -34,18 +35,15 @@ export function filterImports(current: Sync, target: Partial<Sync>) {
3435
newtarget = manualTimezonesToIntl(newtarget) // 21.0
3536

3637
// Merge both settings
37-
3838
const defaultAbout = { about: { browser: PLATFORM, version: CURRENT_VERSION } }
3939
newcurrent = deepmergeAll(newcurrent, newtarget, defaultAbout) as Sync
4040

41-
// All versions
42-
41+
// After merge only
42+
newcurrent = removeLinkgroupDuplicates(newcurrent)
4343
newcurrent = removeWorldClocksDuplicate(newcurrent, newtarget)
44-
newcurrent = convertOldCssSelectors(newcurrent)
4544
newcurrent = toggleMoveWidgets(newcurrent, newtarget)
4645

4746
// Remove old fields
48-
4947
newcurrent.settingssync = undefined
5048
newcurrent.custom_every = undefined
5149
newcurrent.custom_time = undefined
@@ -285,7 +283,7 @@ function validateLinkGroups(current: Import): Import {
285283

286284
for (const link of links) {
287285
if (!link?.parent) {
288-
link.parent = 'default'
286+
link.parent = current.linkgroups.selected
289287
current[link._id] = link
290288
}
291289
}
@@ -302,11 +300,6 @@ function validateLinkGroups(current: Import): Import {
302300
}
303301
}
304302

305-
// Remove duplicate groups
306-
current.linkgroups.groups = [...new Set(current.linkgroups.groups)]
307-
current.linkgroups.pinned = [...new Set(current.linkgroups.pinned)]
308-
current.linkgroups.synced = [...new Set(current.linkgroups.synced)]
309-
310303
// Force enable if multiple groups are hidden
311304
if (current.linkgroups.groups.length > 1) {
312305
current.linkgroups.on = true
@@ -419,6 +412,28 @@ function analogClockOptions<Data extends Sync | Import>(data: Data): Data {
419412
return data
420413
}
421414

415+
function removeLinkgroupDuplicates(current: Sync): Sync {
416+
// 1. Remove duplicate
417+
current.linkgroups.groups = [...new Set(current.linkgroups.groups)]
418+
current.linkgroups.pinned = [...new Set(current.linkgroups.pinned)]
419+
current.linkgroups.synced = [...new Set(current.linkgroups.synced)]
420+
421+
// 2. Remove default from SYNC_DEFAULT
422+
423+
const links = bundleLinks(current)
424+
const parents = links.map((l) => l.parent)
425+
const defaultGroupAsParent = parents.some((parent) => parent === 'default')
426+
const multipleGroups = current.linkgroups.groups.length > 1
427+
428+
if (multipleGroups && !defaultGroupAsParent) {
429+
current.linkgroups.groups = current.linkgroups.groups.filter((item) => item !== 'default')
430+
current.linkgroups.pinned = current.linkgroups.pinned.filter((item) => item !== 'default')
431+
current.linkgroups.synced = current.linkgroups.synced.filter((item) => item !== 'default')
432+
}
433+
434+
return current
435+
}
436+
422437
function toggleMoveWidgets(current: Sync, imported: Import): Sync {
423438
// When import doesn't have move, other widgets can still be different
424439
// This updates current grid with the widgets states from import
@@ -495,7 +510,7 @@ function toggleMoveWidgets(current: Sync, imported: Import): Sync {
495510
return current
496511
}
497512

498-
function convertOldCssSelectors<Data extends Sync | Import>(data: Data): Data {
513+
function convertOldCssSelectors(data: Import): Import {
499514
if (data?.css) {
500515
data.css = data.css
501516
.replaceAll('.block', '.link')
Lines changed: 16 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"browser": "firefox",
44
"version": "20.4.2"
55
},
6-
"showall": true,
6+
"showall": false,
77
"lang": "en",
88
"dark": "system",
99
"favicon": "",
@@ -14,14 +14,14 @@
1414
"time": true,
1515
"main": true,
1616
"dateformat": "auto",
17-
"background_blur": 0,
18-
"background_bright": 0.35,
19-
"background_type": "local",
17+
"background_blur": 15,
18+
"background_bright": 0.8,
19+
"background_type": "unsplash",
2020
"quicklinks": true,
2121
"syncbookmarks": null,
2222
"textShadow": 0.2,
2323
"announcements": "major",
24-
"review": -1,
24+
"review": 31,
2525
"css": "",
2626
"hide": {},
2727
"linkstyle": "medium",
@@ -43,9 +43,9 @@
4343
"ampm": false,
4444
"analog": false,
4545
"seconds": false,
46-
"timezone": "Asia/Irkutsk",
4746
"ampmlabel": false,
48-
"worldclocks": true
47+
"timezone": "auto",
48+
"worldclocks": false
4949
},
5050
"analogstyle": {
5151
"face": "none",
@@ -54,21 +54,12 @@
5454
"border": "#ffff",
5555
"background": "#fff2"
5656
},
57-
"worldclocks": [
58-
{
59-
"timezone": "Europe/Paris",
60-
"region": "Clermont-Ferrand"
61-
},
62-
{
63-
"timezone": "America/Sao_Paulo",
64-
"region": "Sao Paulo"
65-
}
66-
],
57+
"worldclocks": [],
6758
"unsplash": {
68-
"every": "tabs",
69-
"collection": "KWcmZT9FkSo",
70-
"lastCollec": "user",
71-
"time": 1746606433306
59+
"every": "hour",
60+
"collection": "",
61+
"lastCollec": "day",
62+
"time": 1747677308677
7263
},
7364
"weather": {
7465
"unit": "metric",
@@ -81,14 +72,14 @@
8172
},
8273
"notes": {
8374
"on": false,
84-
"opacity": 0.1,
8575
"width": 40,
76+
"opacity": 0.1,
8677
"align": "left"
8778
},
8879
"searchbar": {
8980
"on": false,
9081
"opacity": 0.1,
91-
"newtab": true,
82+
"newtab": false,
9283
"suggestions": true,
9384
"engine": "default",
9485
"request": "",
@@ -99,7 +90,7 @@
9990
"author": false,
10091
"type": "classic",
10192
"frequency": "day",
102-
"last": 1746589872934
93+
"last": 1747726990397
10394
},
10495
"font": {
10596
"size": "14",
@@ -115,21 +106,6 @@
115106
},
116107
"move": {
117108
"selection": "single",
118-
"layouts": {
119-
"single": {
120-
"items": {},
121-
"grid": [
122-
[
123-
"time"
124-
],
125-
[
126-
"main"
127-
],
128-
[
129-
"quicklinks"
130-
]
131-
]
132-
}
133-
}
109+
"layouts": {}
134110
}
135111
}

tests/configs/20.4.2.json

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
{
2+
"about": {
3+
"browser": "firefox",
4+
"version": "20.4.2"
5+
},
6+
"showall": true,
7+
"lang": "en",
8+
"dark": "system",
9+
"favicon": "",
10+
"tabtitle": "",
11+
"greeting": "",
12+
"pagegap": 1,
13+
"pagewidth": 1600,
14+
"time": true,
15+
"main": true,
16+
"dateformat": "auto",
17+
"background_blur": 0,
18+
"background_bright": 0.35,
19+
"background_type": "local",
20+
"quicklinks": true,
21+
"syncbookmarks": null,
22+
"textShadow": 0.2,
23+
"announcements": "major",
24+
"review": -1,
25+
"css": "",
26+
"hide": {},
27+
"linkstyle": "medium",
28+
"linktitles": true,
29+
"linkbackgrounds": true,
30+
"linknewtab": false,
31+
"linksrow": 6,
32+
"linkgroups": {
33+
"on": true,
34+
"selected": "Socials",
35+
"groups": ["Dev", "Socials"],
36+
"pinned": ["Dev"],
37+
"synced": []
38+
},
39+
"clock": {
40+
"size": 1,
41+
"ampm": false,
42+
"analog": false,
43+
"seconds": false,
44+
"timezone": "Asia/Irkutsk",
45+
"ampmlabel": false,
46+
"worldclocks": true
47+
},
48+
"analogstyle": {
49+
"face": "none",
50+
"hands": "modern",
51+
"shape": "round",
52+
"border": "#ffff",
53+
"background": "#fff2"
54+
},
55+
"worldclocks": [
56+
{
57+
"timezone": "Europe/Paris",
58+
"region": "Clermont-Ferrand"
59+
},
60+
{
61+
"timezone": "America/Sao_Paulo",
62+
"region": "Sao Paulo"
63+
}
64+
],
65+
"unsplash": {
66+
"every": "tabs",
67+
"collection": "KWcmZT9FkSo",
68+
"lastCollec": "user",
69+
"time": 1746606433306
70+
},
71+
"weather": {
72+
"unit": "metric",
73+
"provider": "",
74+
"moreinfo": "none",
75+
"forecast": "auto",
76+
"temperature": "actual",
77+
"geolocation": "approximate",
78+
"city": "romagnat"
79+
},
80+
"notes": {
81+
"on": false,
82+
"opacity": 0.1,
83+
"width": 40,
84+
"align": "left"
85+
},
86+
"searchbar": {
87+
"on": false,
88+
"opacity": 0.1,
89+
"newtab": true,
90+
"suggestions": true,
91+
"engine": "default",
92+
"request": "",
93+
"placeholder": ""
94+
},
95+
"quotes": {
96+
"on": false,
97+
"author": false,
98+
"type": "classic",
99+
"frequency": "day",
100+
"last": 1746589872934
101+
},
102+
"font": {
103+
"size": "14",
104+
"family": "",
105+
"system": true,
106+
"weightlist": [],
107+
"weight": "300"
108+
},
109+
"supporters": {
110+
"enabled": true,
111+
"closed": true,
112+
"month": 5
113+
},
114+
"move": {
115+
"selection": "single",
116+
"layouts": {
117+
"single": {
118+
"items": {},
119+
"grid": [["time"], ["main"], ["quicklinks"]]
120+
}
121+
}
122+
},
123+
"linkscgnoff": {
124+
"_id": "linkscgnoff",
125+
"order": 0,
126+
"parent": "Socials",
127+
"title": "",
128+
"url": "https://x.com"
129+
},
130+
"linksepjerj": {
131+
"_id": "linksepjerj",
132+
"order": 1,
133+
"parent": "linksijngll",
134+
"title": "",
135+
"url": "https://tahoe.be"
136+
},
137+
"linksijngll": {
138+
"_id": "linksijngll",
139+
"order": 0,
140+
"parent": "Dev",
141+
"title": "",
142+
"folder": true
143+
},
144+
"linkskodlen": {
145+
"_id": "linkskodlen",
146+
"order": 0,
147+
"parent": "linksijngll",
148+
"title": "",
149+
"url": "https://victr.me"
150+
},
151+
"linkskqfoda": {
152+
"_id": "linkskqfoda",
153+
"order": 1,
154+
"parent": "Socials",
155+
"title": "",
156+
"url": "https://ddg.gg"
157+
}
158+
}

0 commit comments

Comments
 (0)