ColorSchemeTab: add download button

SchemeDownloader: fetch available color schemes from noctalia-colorscheme repo
ColorSchemes: move multiple schemes to the colorscheme repo
i18n: add translations to SchemeDownloader
ColorSchemeTab: move into own folder (+ SchemeDownloader)
This commit is contained in:
Ly-sec
2025-11-18 20:39:10 +01:00
parent 1d200e84a1
commit c3b73f02b3
79 changed files with 1328 additions and 1802 deletions

View File

@@ -1,38 +0,0 @@
{
"dark": {
"mPrimary": "#C4A82E",
"mOnPrimary": "#0E1015",
"mSecondary": "#D14358",
"mOnSecondary": "#0E1015",
"mTertiary": "#00A66C",
"mOnTertiary": "#0E1015",
"mError": "#B32D2D",
"mOnError": "#0E1015",
"mSurface": "#0C1017",
"mOnSurface": "#5C8AC4",
"mSurfaceVariant": "#11151D",
"mOnSurfaceVariant": "#9B6BC1",
"mOutline": "#45A0D6",
"mShadow": "#090D13",
"mHover": "#00A66C",
"mOnHover": "#0E1015"
},
"light": {
"mPrimary": "#00B8B3",
"mOnPrimary": "#1A1914",
"mSecondary": "#D957A0",
"mOnSecondary": "#1A1914",
"mTertiary": "#45D395",
"mOnTertiary": "#1A1914",
"mError": "#E63E5D",
"mOnError": "#1A1914",
"mSurface": "#DAE6E8",
"mOnSurface": "#1A1914",
"mSurfaceVariant": "#C8DEE6",
"mOnSurfaceVariant": "#1A1914",
"mOutline": "#7B52AB",
"mShadow": "#B8D4E6",
"mHover": "#45D395",
"mOnHover": "#1A1914"
}
}

View File

@@ -1,33 +0,0 @@
# Colors (Cyberpunk)
[colors.bright]
black = '#2b314a'
blue = '#4f8fff'
cyan = '#43c9ff'
green = '#89d36a'
magenta = '#9d6dff'
red = '#e64572'
white = '#d8e0ff'
yellow = '#d7a23a'
[colors.cursor]
cursor = '#d8e0ff'
text = '#0a0d14'
[colors.normal]
black = '#0c0e14'
blue = '#4f8fff'
cyan = '#43c9ff'
green = '#89d36a'
magenta = '#9d6dff'
red = '#e64572'
white = '#b7c4f2'
yellow = '#d7a23a'
[colors.primary]
background = '#0a0d14'
foreground = '#d8e0ff'
[colors.selection]
background = '#d8e0ff'
text = '#0a0d14'

View File

@@ -1,33 +0,0 @@
# Colors (Cyberpunk Light)
[colors.bright]
black = '#a1a6c5'
blue = '#2e7de9'
cyan = '#007197'
green = '#587539'
magenta = '#9854f1'
red = '#f52a65'
white = '#3760bf'
yellow = '#8c6c3e'
[colors.cursor]
cursor = '#3760bf'
text = '#e1e2e7'
[colors.normal]
black = '#e9e9ed'
blue = '#2e7de9'
cyan = '#007197'
green = '#587539'
magenta = '#9854f1'
red = '#f52a65'
white = '#6172b0'
yellow = '#8c6c3e'
[colors.primary]
background = '#e1e2e7'
foreground = '#3760bf'
[colors.selection]
background = '#99a7df'
text = '#3760bf'

View File

@@ -1,27 +0,0 @@
[cursor]
color=0a0d14 d8e0ff
[colors]
foreground=d8e0ff
background=0a0d14
regular0=0c0e14
regular1=e64572
regular2=89d36a
regular3=d7a23a
regular4=4f8fff
regular5=9d6dff
regular6=43c9ff
regular7=b7c4f2
bright0=2b314a
bright1=e64572
bright2=89d36a
bright3=d7a23a
bright4=4f8fff
bright5=9d6dff
bright6=43c9ff
bright7=d8e0ff
selection-foreground=0a0d14
selection-background=d8e0ff

View File

@@ -1,22 +0,0 @@
[colors]
foreground=3760bf
background=e1e2e7
regular0=e9e9ed
regular1=f52a65
regular2=587539
regular3=8c6c3e
regular4=2e7de9
regular5=9854f1
regular6=007197
regular7=6172b0
bright0=a1a6c5
bright1=f52a65
bright2=587539
bright3=8c6c3e
bright4=2e7de9
bright5=9854f1
bright6=007197
bright7=3760bf
selection-foreground=3760bf
selection-background=99a7df
cursor=e1e2e7 3760bf

View File

@@ -1,23 +0,0 @@
palette = 0=#0c0e14
palette = 1=#e64572
palette = 2=#89d36a
palette = 3=#d7a23a
palette = 4=#4f8fff
palette = 5=#9d6dff
palette = 6=#43c9ff
palette = 7=#b7c4f2
palette = 8=#2b314a
palette = 9=#e64572
palette = 10=#89d36a
palette = 11=#d7a23a
palette = 12=#4f8fff
palette = 13=#9d6dff
palette = 14=#43c9ff
palette = 15=#d8e0ff
background = #0a0d14
foreground = #d8e0ff
cursor-color = #d8e0ff
cursor-text = #0a0d14
selection-background = #d8e0ff
selection-foreground = #0a0d14

View File

@@ -1,22 +0,0 @@
palette = 0=#e9e9ed
palette = 1=#f52a65
palette = 2=#587539
palette = 3=#8c6c3e
palette = 4=#2e7de9
palette = 5=#9854f1
palette = 6=#007197
palette = 7=#6172b0
palette = 8=#a1a6c5
palette = 9=#f52a65
palette = 10=#587539
palette = 11=#8c6c3e
palette = 12=#2e7de9
palette = 13=#9854f1
palette = 14=#007197
palette = 15=#3760bf
background = #e1e2e7
foreground = #3760bf
cursor-color = #3760bf
cursor-text = #e1e2e7
selection-background = #99a7df
selection-foreground = #3760bf

View File

@@ -1,23 +0,0 @@
color0 #0c0e14
color1 #e64572
color2 #89d36a
color3 #d7a23a
color4 #4f8fff
color5 #9d6dff
color6 #43c9ff
color7 #b7c4f2
color8 #2b314a
color9 #e64572
color10 #89d36a
color11 #d7a23a
color12 #4f8fff
color13 #9d6dff
color14 #43c9ff
color15 #d8e0ff
background #0a0d14
selection_foreground #0a0d14
cursor #d8e0ff
cursor_text_color #0a0d14
foreground #d8e0ff
selection_background #d8e0ff

View File

@@ -1,22 +0,0 @@
color0 #e9e9ed
color1 #f52a65
color2 #587539
color3 #8c6c3e
color4 #2e7de9
color5 #9854f1
color6 #007197
color7 #6172b0
color8 #a1a6c5
color9 #f52a65
color10 #587539
color11 #8c6c3e
color12 #2e7de9
color13 #9854f1
color14 #007197
color15 #3760bf
background #e1e2e7
selection_foreground #e1e2e7
cursor #3760bf
cursor_text_color #e1e2e7
foreground #3760bf
selection_background #3760bf

View File

@@ -1,31 +0,0 @@
[colors]
ansi = [
"#0c0e14",
"#e64572",
"#89d36a",
"#d7a23a",
"#4f8fff",
"#9d6dff",
"#43c9ff",
"#b7c4f2",
]
background = "#0a0d14"
brights = [
"#2b314a",
"#e64572",
"#89d36a",
"#d7a23a",
"#4f8fff",
"#9d6dff",
"#43c9ff",
"#d8e0ff",
]
cursor_bg = "#d8e0ff"
cursor_border = "#d8e0ff"
cursor_fg = "#0a0d14"
foreground = "#d8e0ff"
selection_bg = "#d8e0ff"
selection_fg = "#0a0d14"
[metadata]
name = "Noctalia"

View File

@@ -1,31 +0,0 @@
[colors]
ansi = [
"#e9e9ed",
"#f52a65",
"#587539",
"#8c6c3e",
"#2e7de9",
"#9854f1",
"#007197",
"#6172b0",
]
background = "#e1e2e7"
brights = [
"#a1a6c5",
"#f52a65",
"#587539",
"#8c6c3e",
"#2e7de9",
"#9854f1",
"#007197",
"#3760bf",
]
cursor_bg = "#3760bf"
cursor_border = "#3760bf"
cursor_fg = "#e1e2e7"
foreground = "#3760bf"
selection_bg = "#3760bf"
selection_fg = "#e1e2e7"
[metadata]
name = "Noctalia"

View File

@@ -1,38 +0,0 @@
{
"dark": {
"mPrimary": "#D3C6AA",
"mOnPrimary": "#232A2E",
"mSecondary": "#D3C6AA",
"mOnSecondary": "#232A2E",
"mTertiary": "#9DA9A0",
"mOnTertiary": "#232A2E",
"mError": "#E67E80",
"mOnError": "#232A2E",
"mSurface": "#232A2E",
"mOnSurface": "#859289",
"mSurfaceVariant": "#2D353B",
"mOnSurfaceVariant": "#D3C6AA",
"mOutline": "#D3C6AA",
"mShadow": "#475258",
"mHover": "#9DA9A0",
"mOnHover": "#232A2E"
},
"light": {
"mPrimary": "#434F55",
"mOnPrimary": "#D3C6AA",
"mSecondary": "#232a2e",
"mOnSecondary": "#D3C6AA",
"mTertiary": "#333c43",
"mOnTertiary": "#9DA9A0",
"mError": "#E66868",
"mOnError": "#9DA9A0",
"mSurface": "#9DA9A0",
"mOnSurface": "#232A2E",
"mSurfaceVariant": "#BEC5B2",
"mOnSurfaceVariant": "#333C43",
"mOutline": "#232A2E",
"mShadow": "#ECF5ED",
"mHover": "#333c43",
"mOnHover": "#9DA9A0"
}
}

View File

@@ -1,33 +0,0 @@
# Colors (Everforest Dark Hard)
[colors.bright]
black = '#a6b0a0'
blue = '#3a94c5'
cyan = '#35a77c'
green = '#8da101'
magenta = '#df69ba'
red = '#f85552'
white = '#fffbef'
yellow = '#dfa000'
[colors.cursor]
cursor = '#e69875'
text = '#4c3743'
[colors.normal]
black = '#7a8478'
blue = '#7fbbb3'
cyan = '#83c092'
green = '#a7c080'
magenta = '#d699b6'
red = '#e67e80'
white = '#f2efdf'
yellow = '#dbbc7f'
[colors.primary]
background = '#1e2326'
foreground = '#d3c6aa'
[colors.selection]
background = '#4c3743'
text = '#d3c6aa'

View File

@@ -1,33 +0,0 @@
# Colors (Everforest Light Med)
[colors.bright]
black = '#a6b0a0'
blue = '#3a94c5'
cyan = '#35a77c'
green = '#8da101'
magenta = '#df69ba'
red = '#f85552'
white = '#fffbef'
yellow = '#dfa000'
[colors.cursor]
cursor = '#f57d26'
text = '#eaedc8'
[colors.normal]
black = '#7a8478'
blue = '#7fbbb3'
cyan = '#83c092'
green = '#9ab373'
magenta = '#d699b6'
red = '#e67e80'
white = '#b2af9f'
yellow = '#c1a266'
[colors.primary]
background = '#efebd4'
foreground = '#5c6a72'
[colors.selection]
background = '#eaedc8'
text = '#5c6a72'

View File

@@ -1,22 +0,0 @@
[colors]
foreground=d3c6aa
background=1e2326
regular0=7a8478
regular1=e67e80
regular2=a7c080
regular3=dbbc7f
regular4=7fbbb3
regular5=d699b6
regular6=83c092
regular7=f2efdf
bright0=a6b0a0
bright1=f85552
bright2=8da101
bright3=dfa000
bright4=3a94c5
bright5=df69ba
bright6=35a77c
bright7=fffbef
selection-foreground=d3c6aa
selection-background=4c3743
cursor=4c3743 e69875

View File

@@ -1,22 +0,0 @@
[colors]
foreground=5c6a72
background=efebd4
regular0=7a8478
regular1=e67e80
regular2=9ab373
regular3=c1a266
regular4=7fbbb3
regular5=d699b6
regular6=83c092
regular7=b2af9f
bright0=a6b0a0
bright1=f85552
bright2=8da101
bright3=dfa000
bright4=3a94c5
bright5=df69ba
bright6=35a77c
bright7=fffbef
selection-foreground=5c6a72
selection-background=eaedc8
cursor=eaedc8 f57d26

View File

@@ -1,22 +0,0 @@
palette = 0=#7a8478
palette = 1=#e67e80
palette = 2=#a7c080
palette = 3=#dbbc7f
palette = 4=#7fbbb3
palette = 5=#d699b6
palette = 6=#83c092
palette = 7=#f2efdf
palette = 8=#a6b0a0
palette = 9=#f85552
palette = 10=#8da101
palette = 11=#dfa000
palette = 12=#3a94c5
palette = 13=#df69ba
palette = 14=#35a77c
palette = 15=#fffbef
background = #1e2326
foreground = #d3c6aa
cursor-color = #e69875
cursor-text = #4c3743
selection-background = #4c3743
selection-foreground = #d3c6aa

View File

@@ -1,22 +0,0 @@
palette = 0=#7a8478
palette = 1=#e67e80
palette = 2=#9ab373
palette = 3=#c1a266
palette = 4=#7fbbb3
palette = 5=#d699b6
palette = 6=#83c092
palette = 7=#b2af9f
palette = 8=#a6b0a0
palette = 9=#f85552
palette = 10=#8da101
palette = 11=#dfa000
palette = 12=#3a94c5
palette = 13=#df69ba
palette = 14=#35a77c
palette = 15=#fffbef
background = #efebd4
foreground = #5c6a72
cursor-color = #f57d26
cursor-text = #eaedc8
selection-background = #eaedc8
selection-foreground = #5c6a72

View File

@@ -1,22 +0,0 @@
color0 #7a8478
color1 #e67e80
color2 #a7c080
color3 #dbbc7f
color4 #7fbbb3
color5 #d699b6
color6 #83c092
color7 #f2efdf
color8 #a6b0a0
color9 #f85552
color10 #8da101
color11 #dfa000
color12 #3a94c5
color13 #df69ba
color14 #35a77c
color15 #fffbef
background #1e2326
selection_foreground #1e2326
cursor #e69875
cursor_text_color #4c3743
foreground #d3c6aa
selection_background #d3c6aa

View File

@@ -1,22 +0,0 @@
color0 #7a8478
color1 #e67e80
color2 #9ab373
color3 #c1a266
color4 #7fbbb3
color5 #d699b6
color6 #83c092
color7 #b2af9f
color8 #a6b0a0
color9 #f85552
color10 #8da101
color11 #dfa000
color12 #3a94c5
color13 #df69ba
color14 #35a77c
color15 #fffbef
background #efebd4
selection_foreground #efebd4
cursor #f57d26
cursor_text_color #eaedc8
foreground #5c6a72
selection_background #5c6a72

View File

@@ -1,33 +0,0 @@
[colors]
ansi = [
"#4b565c",
"#e67e80",
"#a7c080",
"#dbbc7f",
"#7fbbb3",
"#d699b6",
"#83c092",
"#d3c6aa",
]
background = "#2d353b"
brights = [
"#5c6a72",
"#f85552",
"#8da101",
"#dfa000",
"#3a94c5",
"#df69ba",
"#35a77c",
"#dfddc8",
]
cursor_bg = "#d3c6aa"
cursor_border = "#d3c6aa"
cursor_fg = "#2d353b"
foreground = "#d3c6aa"
[colors.indexed]
[metadata]
name = "Noctalia"

View File

@@ -1,31 +0,0 @@
[colors]
ansi = [
"#5c6a72",
"#f85552",
"#8da101",
"#dfa000",
"#3a94c5",
"#df69ba",
"#35a77c",
"#dfddc8",
]
background = "#fdf6e3"
brights = [
"#4b565c",
"#e67e80",
"#a7c080",
"#dbbc7f",
"#7fbbb3",
"#d699b6",
"#83c092",
"#d3c6aa",
]
cursor_bg = "#5c6a72"
cursor_border = "#5c6a72"
cursor_fg = "#fdf6e3"
foreground = "#5c6a72"
[colors.indexed]
[metadata]
name = "Noctalia"

View File

@@ -1,38 +0,0 @@
{
"dark": {
"mPrimary": "#aaaaaa",
"mOnPrimary": "#111111",
"mSecondary": "#a7a7a7",
"mOnSecondary": "#111111",
"mTertiary": "#cccccc",
"mOnTertiary": "#111111",
"mError": "#dddddd",
"mOnError": "#111111",
"mSurface": "#111111",
"mOnSurface": "#828282",
"mSurfaceVariant": "#191919",
"mOnSurfaceVariant": "#5d5d5d",
"mOutline": "#3c3c3c",
"mShadow": "#000000",
"mHover": "#cccccc",
"mOnHover": "#111111"
},
"light": {
"mPrimary": "#555555",
"mOnPrimary": "#eeeeee",
"mSecondary": "#505058",
"mOnSecondary": "#eeeeee",
"mTertiary": "#333333",
"mOnTertiary": "#eeeeee",
"mError": "#222222",
"mOnError": "#efefef",
"mSurface": "#d4d4d4",
"mOnSurface": "#696969",
"mSurfaceVariant": "#e8e8e8",
"mOnSurfaceVariant": "#9e9e9e",
"mOutline": "#c3c3c3",
"mShadow": "#fafafa",
"mHover": "#333333",
"mOnHover": "#eeeeee"
}
}

View File

@@ -1,33 +0,0 @@
# Colors (Monochrome)
[colors.bright]
black = '#3c3c3c'
blue = '#a7a7a7'
cyan = '#cccccc'
green = '#cccccc'
magenta = '#dddddd'
red = '#dddddd'
white = '#ffffff'
yellow = '#aaaaaa'
[colors.cursor]
cursor = '#aaaaaa'
text = '#111111'
[colors.normal]
black = '#191919'
blue = '#a7a7a7'
cyan = '#cccccc'
green = '#cccccc'
magenta = '#dddddd'
red = '#dddddd'
white = '#828282'
yellow = '#aaaaaa'
[colors.primary]
background = '#111111'
foreground = '#828282'
[colors.selection]
background = '#828282'
text = '#111111'

View File

@@ -1,33 +0,0 @@
# Colors (Monochrome Light)
[colors.bright]
black = '#c3c3c3'
blue = '#505058'
cyan = '#333333'
green = '#333333'
magenta = '#222222'
red = '#222222'
white = '#000000'
yellow = '#555555'
[colors.cursor]
cursor = '#555555'
text = '#d4d4d4'
[colors.normal]
black = '#e8e8e8'
blue = '#505058'
cyan = '#333333'
green = '#333333'
magenta = '#222222'
red = '#222222'
white = '#696969'
yellow = '#555555'
[colors.primary]
background = '#d4d4d4'
foreground = '#696969'
[colors.selection]
background = '#696969'
text = '#d4d4d4'

View File

@@ -1,22 +0,0 @@
[colors]
foreground=828282
background=111111
regular0=191919
regular1=dddddd
regular2=cccccc
regular3=aaaaaa
regular4=a7a7a7
regular5=dddddd
regular6=cccccc
regular7=828282
bright0=3c3c3c
bright1=dddddd
bright2=cccccc
bright3=aaaaaa
bright4=a7a7a7
bright5=dddddd
bright6=cccccc
bright7=ffffff
selection-foreground=111111
selection-background=828282
cursor=111111 aaaaaa

View File

@@ -1,22 +0,0 @@
[colors]
foreground=696969
background=d4d4d4
regular0=e8e8e8
regular1=222222
regular2=333333
regular3=555555
regular4=505058
regular5=222222
regular6=333333
regular7=696969
bright0=c3c3c3
bright1=222222
bright2=333333
bright3=555555
bright4=505058
bright5=222222
bright6=333333
bright7=000000
selection-foreground=d4d4d4
selection-background=696969
cursor=d4d4d4 555555

View File

@@ -1,22 +0,0 @@
palette = 0=#191919
palette = 1=#dddddd
palette = 2=#cccccc
palette = 3=#aaaaaa
palette = 4=#a7a7a7
palette = 5=#dddddd
palette = 6=#cccccc
palette = 7=#828282
palette = 8=#3c3c3c
palette = 9=#dddddd
palette = 10=#cccccc
palette = 11=#aaaaaa
palette = 12=#a7a7a7
palette = 13=#dddddd
palette = 14=#cccccc
palette = 15=#ffffff
background = #111111
foreground = #828282
cursor-color = #aaaaaa
cursor-text = #111111
selection-background = #828282
selection-foreground = #111111

View File

@@ -1,22 +0,0 @@
palette = 0=#e8e8e8
palette = 1=#222222
palette = 2=#333333
palette = 3=#555555
palette = 4=#505058
palette = 5=#222222
palette = 6=#333333
palette = 7=#696969
palette = 8=#c3c3c3
palette = 9=#222222
palette = 10=#333333
palette = 11=#555555
palette = 12=#505058
palette = 13=#222222
palette = 14=#333333
palette = 15=#000000
background = #d4d4d4
foreground = #696969
cursor-color = #555555
cursor-text = #d4d4d4
selection-background = #696969
selection-foreground = #d4d4d4

View File

@@ -1,22 +0,0 @@
color0 #191919
color1 #dddddd
color2 #cccccc
color3 #aaaaaa
color4 #a7a7a7
color5 #dddddd
color6 #cccccc
color7 #828282
color8 #3c3c3c
color9 #dddddd
color10 #cccccc
color11 #aaaaaa
color12 #a7a7a7
color13 #dddddd
color14 #cccccc
color15 #ffffff
background #111111
selection_foreground #111111
cursor #aaaaaa
cursor_text_color #111111
foreground #828282
selection_background #828282

View File

@@ -1,22 +0,0 @@
color0 #e8e8e8
color1 #222222
color2 #333333
color3 #555555
color4 #505058
color5 #222222
color6 #333333
color7 #696969
color8 #c3c3c3
color9 #222222
color10 #333333
color11 #555555
color12 #505058
color13 #222222
color14 #333333
color15 #000000
background #d4d4d4
selection_foreground #d4d4d4
cursor #555555
cursor_text_color #d4d4d4
foreground #696969
selection_background #696969

View File

@@ -1,31 +0,0 @@
[colors]
ansi = [
"#191919",
"#dddddd",
"#cccccc",
"#aaaaaa",
"#a7a7a7",
"#dddddd",
"#cccccc",
"#828282",
]
background = "#111111"
brights = [
"#3c3c3c",
"#dddddd",
"#cccccc",
"#aaaaaa",
"#a7a7a7",
"#dddddd",
"#cccccc",
"#ffffff",
]
cursor_bg = "#aaaaaa"
cursor_border = "#aaaaaa"
cursor_fg = "#111111"
foreground = "#828282"
selection_bg = "#828282"
selection_fg = "#111111"
[metadata]
name = "Noctalia"

View File

@@ -1,31 +0,0 @@
[colors]
ansi = [
"#e8e8e8",
"#222222",
"#333333",
"#555555",
"#505058",
"#222222",
"#333333",
"#696969",
]
background = "#d4d4d4"
brights = [
"#c3c3c3",
"#222222",
"#333333",
"#555555",
"#505058",
"#222222",
"#333333",
"#000000",
]
cursor_bg = "#555555"
cursor_border = "#555555"
cursor_fg = "#d4d4d4"
foreground = "#696969"
selection_bg = "#696969"
selection_fg = "#d4d4d4"
[metadata]
name = "Noctalia"

View File

@@ -1,38 +0,0 @@
{
"dark": {
"mPrimary": "#c7a1d8",
"mOnPrimary": "#1a151f",
"mSecondary": "#a984c4",
"mOnSecondary": "#f3edf7",
"mTertiary": "#e0b7c9",
"mOnTertiary": "#20161f",
"mError": "#e9899d",
"mOnError": "#1e1418",
"mSurface": "#1c1822",
"mOnSurface": "#e9e4f0",
"mSurfaceVariant": "#262130",
"mOnSurfaceVariant": "#a79ab0",
"mOutline": "#3e364e",
"mShadow": "#120f18",
"mHover": "#e0b7c9",
"mOnHover": "#20161f"
},
"light": {
"mPrimary": "#9b59ba",
"mOnPrimary": "#ffffff",
"mSecondary": "#784999",
"mOnSecondary": "#ffffff",
"mTertiary": "#c17093",
"mOnTertiary": "#ffffff",
"mError": "#e9899d",
"mOnError": "#1e1418",
"mSurface": "#f5f1fa",
"mOnSurface": "#1c1822",
"mSurfaceVariant": "#e7dfee",
"mOnSurfaceVariant": "#4a3d59",
"mOutline": "#cebedc",
"mShadow": "#ffffff",
"mHover": "#c17093",
"mOnHover": "#ffffff"
}
}

View File

@@ -1,33 +0,0 @@
# Colors (Noctalia Legacy)
[colors.bright]
black = '#3e364e'
blue = '#a984c4'
cyan = '#e0b7c9'
green = '#e0b7c9'
magenta = '#e9899d'
red = '#e9899d'
white = '#ffffff'
yellow = '#c7a1d8'
[colors.cursor]
cursor = '#c7a1d8'
text = '#1c1822'
[colors.normal]
black = '#262130'
blue = '#a984c4'
cyan = '#e0b7c9'
green = '#e0b7c9'
magenta = '#e9899d'
red = '#e9899d'
white = '#e9e4f0'
yellow = '#c7a1d8'
[colors.primary]
background = '#1c1822'
foreground = '#e9e4f0'
[colors.selection]
background = '#e9e4f0'
text = '#1c1822'

View File

@@ -1,33 +0,0 @@
# Colors (Noctalia Legacy Light)
[colors.bright]
black = '#cebedc'
blue = '#784999'
cyan = '#c17093'
green = '#c17093'
magenta = '#e9899d'
red = '#e9899d'
white = '#1c1822'
yellow = '#9b59ba'
[colors.cursor]
cursor = '#9b59ba'
text = '#f5f1fa'
[colors.normal]
black = '#e7dfee'
blue = '#784999'
cyan = '#c17093'
green = '#c17093'
magenta = '#e9899d'
red = '#e9899d'
white = '#1c1822'
yellow = '#9b59ba'
[colors.primary]
background = '#f5f1fa'
foreground = '#1c1822'
[colors.selection]
background = '#1c1822'
text = '#f5f1fa'

View File

@@ -1,22 +0,0 @@
[colors]
foreground=e9e4f0
background=1c1822
regular0=262130
regular1=e9899d
regular2=e0b7c9
regular3=c7a1d8
regular4=a984c4
regular5=e9899d
regular6=e0b7c9
regular7=e9e4f0
bright0=3e364e
bright1=e9899d
bright2=e0b7c9
bright3=c7a1d8
bright4=a984c4
bright5=e9899d
bright6=e0b7c9
bright7=ffffff
selection-foreground=1c1822
selection-background=e9e4f0
cursor=1c1822 c7a1d8

View File

@@ -1,22 +0,0 @@
[colors]
foreground=1c1822
background=f5f1fa
regular0=e7dfee
regular1=e9899d
regular2=c17093
regular3=9b59ba
regular4=784999
regular5=e9899d
regular6=c17093
regular7=1c1822
bright0=cebedc
bright1=e9899d
bright2=c17093
bright3=9b59ba
bright4=784999
bright5=e9899d
bright6=c17093
bright7=1c1822
selection-foreground=f5f1fa
selection-background=1c1822
cursor=f5f1fa 9b59ba

View File

@@ -1,22 +0,0 @@
palette = 0=#262130
palette = 1=#e9899d
palette = 2=#e0b7c9
palette = 3=#c7a1d8
palette = 4=#a984c4
palette = 5=#e9899d
palette = 6=#e0b7c9
palette = 7=#e9e4f0
palette = 8=#3e364e
palette = 9=#e9899d
palette = 10=#e0b7c9
palette = 11=#c7a1d8
palette = 12=#a984c4
palette = 13=#e9899d
palette = 14=#e0b7c9
palette = 15=#ffffff
background = #1c1822
foreground = #e9e4f0
cursor-color = #c7a1d8
cursor-text = #1c1822
selection-background = #e9e4f0
selection-foreground = #1c1822

View File

@@ -1,22 +0,0 @@
palette = 0=#e7dfee
palette = 1=#e9899d
palette = 2=#c17093
palette = 3=#9b59ba
palette = 4=#784999
palette = 5=#e9899d
palette = 6=#c17093
palette = 7=#1c1822
palette = 8=#cebedc
palette = 9=#e9899d
palette = 10=#c17093
palette = 11=#9b59ba
palette = 12=#784999
palette = 13=#e9899d
palette = 14=#c17093
palette = 15=#1c1822
background = #f5f1fa
foreground = #1c1822
cursor-color = #9b59ba
cursor-text = #f5f1fa
selection-background = #1c1822
selection-foreground = #f5f1fa

View File

@@ -1,22 +0,0 @@
color0 #262130
color1 #e9899d
color2 #e0b7c9
color3 #c7a1d8
color4 #a984c4
color5 #e9899d
color6 #e0b7c9
color7 #e9e4f0
color8 #3e364e
color9 #e9899d
color10 #e0b7c9
color11 #c7a1d8
color12 #a984c4
color13 #e9899d
color14 #e0b7c9
color15 #ffffff
background #1c1822
selection_foreground #1c1822
cursor #c7a1d8
cursor_text_color #1c1822
foreground #e9e4f0
selection_background #e9e4f0

View File

@@ -1,22 +0,0 @@
color0 #e7dfee
color1 #e9899d
color2 #c17093
color3 #9b59ba
color4 #784999
color5 #e9899d
color6 #c17093
color7 #1c1822
color8 #cebedc
color9 #e9899d
color10 #c17093
color11 #9b59ba
color12 #784999
color13 #e9899d
color14 #c17093
color15 #1c1822
background #f5f1fa
selection_foreground #f5f1fa
cursor #9b59ba
cursor_text_color #f5f1fa
foreground #1c1822
selection_background #1c1822

View File

@@ -1,31 +0,0 @@
[colors]
ansi = [
"#262130",
"#e9899d",
"#e0b7c9",
"#c7a1d8",
"#a984c4",
"#e9899d",
"#e0b7c9",
"#e9e4f0",
]
background = "#1c1822"
brights = [
"#3e364e",
"#e9899d",
"#e0b7c9",
"#c7a1d8",
"#a984c4",
"#e9899d",
"#e0b7c9",
"#ffffff",
]
cursor_bg = "#c7a1d8"
cursor_border = "#c7a1d8"
cursor_fg = "#1c1822"
foreground = "#e9e4f0"
selection_bg = "#e9e4f0"
selection_fg = "#1c1822"
[metadata]
name = "Noctalia"

View File

@@ -1,31 +0,0 @@
[colors]
ansi = [
"#e7dfee",
"#e9899d",
"#c17093",
"#9b59ba",
"#784999",
"#e9899d",
"#c17093",
"#1c1822",
]
background = "#f5f1fa"
brights = [
"#cebedc",
"#e9899d",
"#c17093",
"#9b59ba",
"#784999",
"#e9899d",
"#c17093",
"#1c1822",
]
cursor_bg = "#9b59ba"
cursor_border = "#9b59ba"
cursor_fg = "#f5f1fa"
foreground = "#1c1822"
selection_bg = "#1c1822"
selection_fg = "#f5f1fa"
[metadata]
name = "Noctalia"

View File

@@ -1,38 +0,0 @@
{
"dark": {
"mPrimary": "#1E9177",
"mOnPrimary": "#B8C8C4",
"mSecondary": "#167A63",
"mOnSecondary": "#B8C8C4",
"mTertiary": "#26A589",
"mOnTertiary": "#B8C8C4",
"mError": "#933636",
"mOnError": "#B8C8C4",
"mSurface": "#081512",
"mOnSurface": "#A6B5B1",
"mSurfaceVariant": "#0F251F",
"mOnSurfaceVariant": "#99A8A4",
"mOutline": "#1B6352",
"mShadow": "#040A09",
"mHover": "#26A589",
"mOnHover": "#B8C8C4"
},
"light": {
"mPrimary": "#3B7561",
"mOnPrimary": "#D8E5DB",
"mSecondary": "#526E4A",
"mOnSecondary": "#D8E5DB",
"mTertiary": "#4A8069",
"mOnTertiary": "#D8E5DB",
"mError": "#854145",
"mOnError": "#D8E5DB",
"mSurface": "#AEC2B4",
"mOnSurface": "#2C3D35",
"mSurfaceVariant": "#95AD9C",
"mOnSurfaceVariant": "#263731",
"mOutline": "#5C7A6A",
"mShadow": "#8A9E90",
"mHover": "#4A8069",
"mOnHover": "#D8E5DB"
}
}

View File

@@ -1,33 +0,0 @@
# Colors (Osaka Jade)
[colors.bright]
black = '#464e50'
blue = '#71baf2'
cyan = '#67cbe7'
green = '#96d988'
magenta = '#ce89df'
red = '#ef7e7e'
white = '#bdc3c2'
yellow = '#f4d67a'
[colors.cursor]
cursor = '#dadada'
text = '#141b1e'
[colors.normal]
black = '#232a2d'
blue = '#67b0e8'
cyan = '#6cbfbf'
green = '#8ccf7e'
magenta = '#c47fd5'
red = '#e57474'
white = '#b3b9b8'
yellow = '#e5c76b'
[colors.primary]
background = '#141b1e'
foreground = '#dadada'
[colors.selection]
background = '#141b1e'
text = '#dadada'

View File

@@ -1,33 +0,0 @@
# Colors (Osaka Jade Light)
[colors.bright]
black = '#a6b0a0'
blue = '#3a94c5'
cyan = '#35a77c'
green = '#8da101'
magenta = '#df69ba'
red = '#f85552'
white = '#fffbef'
yellow = '#dfa000'
[colors.cursor]
cursor = '#f57d26'
text = '#eaedc8'
[colors.normal]
black = '#7a8478'
blue = '#7fbbb3'
cyan = '#83c092'
green = '#9ab373'
magenta = '#d699b6'
red = '#e67e80'
white = '#b2af9f'
yellow = '#c1a266'
[colors.primary]
background = '#efebd4'
foreground = '#5c6a72'
[colors.selection]
background = '#eaedc8'
text = '#5c6a72'

View File

@@ -1,25 +0,0 @@
[cursor]
color=141b1e dadada
[colors]
foreground=dadada
background=141b1e
regular0=232a2d
regular1=e57474
regular2=8ccf7e
regular3=e5c76b
regular4=67b0e8
regular5=c47fd5
regular6=6cbfbf
regular7=b3b9b8
bright0=464e50
bright1=ef7e7e
bright2=96d988
bright3=f4d67a
bright4=71baf2
bright5=ce89df
bright6=67cbe7
bright7=bdc3c2
selection-foreground=dadada
selection-background=141b1e

View File

@@ -1,22 +0,0 @@
[colors]
foreground=5c6a72
background=efebd4
regular0=7a8478
regular1=e67e80
regular2=9ab373
regular3=c1a266
regular4=7fbbb3
regular5=d699b6
regular6=83c092
regular7=b2af9f
bright0=a6b0a0
bright1=f85552
bright2=8da101
bright3=dfa000
bright4=3a94c5
bright5=df69ba
bright6=35a77c
bright7=fffbef
selection-foreground=5c6a72
selection-background=eaedc8
cursor=eaedc8 f57d26

View File

@@ -1,22 +0,0 @@
palette = 0=#232a2d
palette = 1=#e57474
palette = 2=#8ccf7e
palette = 3=#e5c76b
palette = 4=#67b0e8
palette = 5=#c47fd5
palette = 6=#6cbfbf
palette = 7=#b3b9b8
palette = 8=#464e50
palette = 9=#ef7e7e
palette = 10=#96d988
palette = 11=#f4d67a
palette = 12=#71baf2
palette = 13=#ce89df
palette = 14=#67cbe7
palette = 15=#bdc3c2
background = #141b1e
foreground = #dadada
cursor-color = #dadada
cursor-text = #141b1e
selection-background = #141b1e
selection-foreground = #dadada

View File

@@ -1,22 +0,0 @@
palette = 0=#7a8478
palette = 1=#e67e80
palette = 2=#9ab373
palette = 3=#c1a266
palette = 4=#7fbbb3
palette = 5=#d699b6
palette = 6=#83c092
palette = 7=#b2af9f
palette = 8=#a6b0a0
palette = 9=#f85552
palette = 10=#8da101
palette = 11=#dfa000
palette = 12=#3a94c5
palette = 13=#df69ba
palette = 14=#35a77c
palette = 15=#fffbef
background = #efebd4
foreground = #5c6a72
cursor-color = #f57d26
cursor-text = #eaedc8
selection-background = #eaedc8
selection-foreground = #5c6a72

View File

@@ -1,22 +0,0 @@
color0 #232a2d
color1 #e57474
color2 #8ccf7e
color3 #e5c76b
color4 #67b0e8
color5 #c47fd5
color6 #6cbfbf
color7 #b3b9b8
color8 #464e50
color9 #ef7e7e
color10 #96d988
color11 #f4d67a
color12 #71baf2
color13 #ce89df
color14 #67cbe7
color15 #bdc3c2
background #141b1e
selection_foreground #141b1e
cursor #dadada
cursor_text_color #141b1e
foreground #dadada
selection_background #dadada

View File

@@ -1,22 +0,0 @@
color0 #7a8478
color1 #e67e80
color2 #9ab373
color3 #c1a266
color4 #7fbbb3
color5 #d699b6
color6 #83c092
color7 #b2af9f
color8 #a6b0a0
color9 #f85552
color10 #8da101
color11 #dfa000
color12 #3a94c5
color13 #df69ba
color14 #35a77c
color15 #fffbef
background #efebd4
selection_foreground #efebd4
cursor #f57d26
cursor_text_color #eaedc8
foreground #5c6a72
selection_background #5c6a72

View File

@@ -1,31 +0,0 @@
[colors]
ansi = [
"#232a2d",
"#e57474",
"#8ccf7e",
"#e5c76b",
"#67b0e8",
"#c47fd5",
"#6cbfbf",
"#b3b9b8",
]
background = "#141b1e"
brights = [
"#464e50",
"#ef7e7e",
"#96d988",
"#f4d67a",
"#71baf2",
"#ce89df",
"#67cbe7",
"#bdc3c2",
]
cursor_bg = "#dadada"
cursor_border = "#dadada"
cursor_fg = "#141b1e"
foreground = "#dadada"
selection_bg = "#dadada"
selection_fg = "#141b1e"
[metadata]
name = "Noctalia"

View File

@@ -1,32 +0,0 @@
[colors]
ansi = [
"#7a8478",
"#e67e80",
"#9ab373",
"#c1a266",
"#7fbbb3",
"#d699b6",
"#83c092",
"#b2af9f",
]
background = "#efebd4"
brights = [
"#a6b0a0",
"#f85552",
"#8da101",
"#dfa000",
"#3a94c5",
"#df69ba",
"#35a77c",
"#fffbef",
]
cursor_bg = "#f57d26"
cursor_border = "#f57d26"
cursor_fg = "#eaedc8"
foreground = "#5c6a72"
selection_bg = "#5c6a72"
selection_fg = "#efebd4"
[metadata]
name = "Noctalia"

View File

@@ -1,38 +0,0 @@
{
"dark": {
"mPrimary": "#b58900",
"mOnPrimary": "#002b36",
"mSecondary": "#d33682",
"mOnSecondary": "#002b36",
"mTertiary": "#cb4b16",
"mOnTertiary": "#002b36",
"mError": "#dc322f",
"mOnError": "#002b36",
"mSurface": "#002b36",
"mOnSurface": "#839496",
"mSurfaceVariant": "#073642",
"mOnSurfaceVariant": "#657b83",
"mOutline": "#0c5c70",
"mShadow": "#002b36",
"mHover": "#cb4b16",
"mOnHover": "#002b36"
},
"light": {
"mPrimary": "#b58900",
"mOnPrimary": "#fdf6e3",
"mSecondary": "#d33682",
"mOnSecondary": "#fdf6e3",
"mTertiary": "#cb4b16",
"mOnTertiary": "#fdf6e3",
"mError": "#dc322f",
"mOnError": "#fdf6e3",
"mSurface": "#fdf6e3",
"mOnSurface": "#657b83",
"mSurfaceVariant": "#eee8d5",
"mOnSurfaceVariant": "#839496",
"mOutline": "#dfd4b1",
"mShadow": "#eee8d5",
"mHover": "#cb4b16",
"mOnHover": "#fdf6e3"
}
}

View File

@@ -1,33 +0,0 @@
# Colors (Solarized Dark)
[colors.bright]
black = '#335e69'
blue = '#839496'
cyan = '#93a1a1'
green = '#586e75'
magenta = '#6c71c4'
red = '#cb4b16'
white = '#fdf6e3'
yellow = '#657b83'
[colors.cursor]
cursor = '#839496'
text = '#073642'
[colors.normal]
black = '#073642'
blue = '#268bd2'
cyan = '#2aa198'
green = '#859900'
magenta = '#d33682'
red = '#dc322f'
white = '#eee8d5'
yellow = '#b58900'
[colors.primary]
background = '#002b36'
foreground = '#839496'
[colors.selection]
background = '#073642'
text = '#93a1a1'

View File

@@ -1,33 +0,0 @@
# Colors (Solarized Light)
[colors.bright]
black = '#002b36'
blue = '#839496'
cyan = '#93a1a1'
green = '#586e75'
magenta = '#6c71c4'
red = '#cb4b16'
white = '#fdf6e3'
yellow = '#657b83'
[colors.cursor]
cursor = '#657b83'
text = '#eee8d5'
[colors.normal]
black = '#073642'
blue = '#268bd2'
cyan = '#2aa198'
green = '#859900'
magenta = '#d33682'
red = '#dc322f'
white = '#bbb5a2'
yellow = '#b58900'
[colors.primary]
background = '#fdf6e3'
foreground = '#657b83'
[colors.selection]
background = '#eee8d5'
text = '#586e75'

View File

@@ -1,22 +0,0 @@
[colors]
foreground=839496
background=002b36
regular0=073642
regular1=dc322f
regular2=859900
regular3=b58900
regular4=268bd2
regular5=d33682
regular6=2aa198
regular7=eee8d5
bright0=335e69
bright1=cb4b16
bright2=586e75
bright3=657b83
bright4=839496
bright5=6c71c4
bright6=93a1a1
bright7=fdf6e3
selection-foreground=93a1a1
selection-background=073642
cursor=073642 839496

View File

@@ -1,23 +0,0 @@
[colors]
foreground=657b83
background=fdf6e3
regular0=073642
regular1=dc322f
regular2=859900
regular3=b58900
regular4=268bd2
regular5=d33682
regular6=2aa198
regular7=bbb5a2
bright0=002b36
bright1=cb4b16
bright2=586e75
bright3=657b83
bright4=839496
bright5=6c71c4
bright6=93a1a1
bright7=fdf6e3
selection-foreground=586e75
selection-background=eee8d5
cursor=eee8d5 657b83

View File

@@ -1,22 +0,0 @@
palette = 0=#073642
palette = 1=#dc322f
palette = 2=#859900
palette = 3=#b58900
palette = 4=#268bd2
palette = 5=#d33682
palette = 6=#2aa198
palette = 7=#eee8d5
palette = 8=#335e69
palette = 9=#cb4b16
palette = 10=#586e75
palette = 11=#657b83
palette = 12=#839496
palette = 13=#6c71c4
palette = 14=#93a1a1
palette = 15=#fdf6e3
background = #002b36
foreground = #839496
cursor-color = #839496
cursor-text = #073642
selection-background = #073642
selection-foreground = #93a1a1

View File

@@ -1,22 +0,0 @@
palette = 0=#073642
palette = 1=#dc322f
palette = 2=#859900
palette = 3=#b58900
palette = 4=#268bd2
palette = 5=#d33682
palette = 6=#2aa198
palette = 7=#bbb5a2
palette = 8=#002b36
palette = 9=#cb4b16
palette = 10=#586e75
palette = 11=#657b83
palette = 12=#839496
palette = 13=#6c71c4
palette = 14=#93a1a1
palette = 15=#fdf6e3
background = #fdf6e3
foreground = #657b83
cursor-color = #657b83
cursor-text = #eee8d5
selection-background = #eee8d5
selection-foreground = #586e75

View File

@@ -1,22 +0,0 @@
color0 #073642
color1 #dc322f
color2 #859900
color3 #b58900
color4 #268bd2
color5 #d33682
color6 #2aa198
color7 #eee8d5
color8 #335e69
color9 #cb4b16
color10 #586e75
color11 #657b83
color12 #839496
color13 #6c71c4
color14 #93a1a1
color15 #fdf6e3
background #002b36
selection_foreground #002b36
cursor #839496
cursor_text_color #073642
foreground #839496
selection_background #839496

View File

@@ -1,22 +0,0 @@
color0 #073642
color1 #dc322f
color2 #859900
color3 #b58900
color4 #268bd2
color5 #d33682
color6 #2aa198
color7 #bbb5a2
color8 #002b36
color9 #cb4b16
color10 #586e75
color11 #657b83
color12 #839496
color13 #6c71c4
color14 #93a1a1
color15 #fdf6e3
background #fdf6e3
selection_foreground #fdf6e3
cursor #657b83
cursor_text_color #eee8d5
foreground #657b83
selection_background #657b83

View File

@@ -1,29 +0,0 @@
[colors]
ansi = [
"#002b36",
"#dc322f",
"#859900",
"#b58900",
"#268bd2",
"#6c71c4",
"#2aa198",
"#93a1a1",
]
background = "#002b36"
brights = [
"#657b83",
"#dc322f",
"#859900",
"#b58900",
"#268bd2",
"#6c71c4",
"#2aa198",
"#fdf6e3",
]
foreground = "#93a1a1"
[colors.indexed]
[metadata]
author = "Chris Kempson"
name = "Noctalia"

View File

@@ -1,30 +0,0 @@
[colors]
ansi = [
"#002b36",
"#dc322f",
"#859900",
"#b58900",
"#268bd2",
"#6c71c4",
"#2aa198",
"#93a1a1",
]
background = "#fdf6e3"
brights = [
"#657b83",
"#dc322f",
"#859900",
"#b58900",
"#268bd2",
"#6c71c4",
"#2aa198",
"#fdf6e3",
]
foreground = "#586e75"
[colors.indexed]
[metadata]
author = "Chris Kempson"
name = "Noctalia"

View File

@@ -1003,6 +1003,41 @@
}
}
},
"download": {
"button": "Mehr herunterladen",
"title": "Farbschemata herunterladen",
"fetching": "Verfügbare Farbschemata werden abgerufen...",
"empty": "Keine Farbschemata verfügbar",
"refresh": "Aktualisieren",
"download": "Herunterladen",
"downloading": "Wird heruntergeladen...",
"delete": "Löschen",
"installed": "Installiert",
"success": {
"title": "Farbschema heruntergeladen",
"description": "{scheme} wurde erfolgreich heruntergeladen"
},
"error": {
"title": "Download fehlgeschlagen",
"description": "Fehler beim Herunterladen von {scheme}",
"invalid-response": "Ungültiges API-Antwortformat",
"parse-failed": "Fehler beim Parsen der API-Antwort: {error}",
"rate-limit": "GitHub API-Ratenlimit überschritten",
"api-error": "API-Fehler: {status}",
"no-files": "Keine Dateien für Schema gefunden",
"download-failed": "Download fehlgeschlagen mit Exit-Code: {code}"
}
},
"delete": {
"success": {
"title": "Farbschema gelöscht",
"description": "{scheme} wurde erfolgreich gelöscht"
},
"error": {
"title": "Löschen fehlgeschlagen",
"description": "Fehler beim Löschen von {scheme}"
}
},
"title": "Farbschema"
},
"control-center": {

View File

@@ -923,6 +923,41 @@
"label": "Predefined color schemes"
}
},
"download": {
"button": "Download more",
"title": "Download Color Schemes",
"fetching": "Fetching available color schemes...",
"empty": "No color schemes available",
"refresh": "Refresh",
"download": "Download",
"downloading": "Downloading...",
"delete": "Delete",
"installed": "Installed",
"success": {
"title": "Color Scheme Downloaded",
"description": "Successfully downloaded {scheme}"
},
"error": {
"title": "Download Failed",
"description": "Failed to download {scheme}",
"invalid-response": "Invalid API response format",
"parse-failed": "Failed to parse API response: {error}",
"rate-limit": "GitHub API rate limit exceeded",
"api-error": "API error: {status}",
"no-files": "No files found for scheme",
"download-failed": "Download failed with exit code: {code}"
}
},
"delete": {
"success": {
"title": "Color Scheme Deleted",
"description": "Successfully deleted {scheme}"
},
"error": {
"title": "Delete Failed",
"description": "Failed to delete {scheme}"
}
},
"templates": {
"misc": {
"description": "Additional configuration options.",

View File

@@ -1003,6 +1003,41 @@
}
}
},
"download": {
"button": "Descargar más",
"title": "Descargar esquemas de colores",
"fetching": "Obteniendo esquemas de colores disponibles...",
"empty": "No hay esquemas de colores disponibles",
"refresh": "Actualizar",
"download": "Descargar",
"downloading": "Descargando...",
"delete": "Eliminar",
"installed": "Instalado",
"success": {
"title": "Esquema de colores descargado",
"description": "{scheme} descargado correctamente"
},
"error": {
"title": "Error al descargar",
"description": "Error al descargar {scheme}",
"invalid-response": "Formato de respuesta de API inválido",
"parse-failed": "Error al analizar la respuesta de la API: {error}",
"rate-limit": "Límite de velocidad de la API de GitHub excedido",
"api-error": "Error de API: {status}",
"no-files": "No se encontraron archivos para el esquema",
"download-failed": "Error al descargar con código de salida: {code}"
}
},
"delete": {
"success": {
"title": "Esquema de colores eliminado",
"description": "{scheme} eliminado correctamente"
},
"error": {
"title": "Error al eliminar",
"description": "Error al eliminar {scheme}"
}
},
"title": "Esquema de colores"
},
"control-center": {

View File

@@ -1003,6 +1003,41 @@
}
}
},
"download": {
"button": "Télécharger plus",
"title": "Télécharger des jeux de couleurs",
"fetching": "Récupération des jeux de couleurs disponibles...",
"empty": "Aucun jeu de couleurs disponible",
"refresh": "Actualiser",
"download": "Télécharger",
"downloading": "Téléchargement...",
"delete": "Supprimer",
"installed": "Installé",
"success": {
"title": "Jeu de couleurs téléchargé",
"description": "{scheme} téléchargé avec succès"
},
"error": {
"title": "Échec du téléchargement",
"description": "Échec du téléchargement de {scheme}",
"invalid-response": "Format de réponse API invalide",
"parse-failed": "Échec de l'analyse de la réponse API: {error}",
"rate-limit": "Limite de débit de l'API GitHub dépassée",
"api-error": "Erreur API: {status}",
"no-files": "Aucun fichier trouvé pour le jeu de couleurs",
"download-failed": "Échec du téléchargement avec le code de sortie: {code}"
}
},
"delete": {
"success": {
"title": "Jeu de couleurs supprimé",
"description": "{scheme} supprimé avec succès"
},
"error": {
"title": "Échec de la suppression",
"description": "Échec de la suppression de {scheme}"
}
},
"title": "Jeu de couleurs"
},
"control-center": {

View File

@@ -1003,6 +1003,41 @@
}
}
},
"download": {
"button": "Meer downloaden",
"title": "Kleurenschema's downloaden",
"fetching": "Beschikbare kleurenschema's ophalen...",
"empty": "Geen kleurenschema's beschikbaar",
"refresh": "Vernieuwen",
"download": "Downloaden",
"downloading": "Downloaden...",
"delete": "Verwijderen",
"installed": "Geïnstalleerd",
"success": {
"title": "Kleurenschema gedownload",
"description": "{scheme} succesvol gedownload"
},
"error": {
"title": "Download mislukt",
"description": "Download van {scheme} mislukt",
"invalid-response": "Ongeldig API-antwoordformaat",
"parse-failed": "Fout bij parseren van API-antwoord: {error}",
"rate-limit": "GitHub API-snelheidslimiet overschreden",
"api-error": "API-fout: {status}",
"no-files": "Geen bestanden gevonden voor schema",
"download-failed": "Download mislukt met afsluitcode: {code}"
}
},
"delete": {
"success": {
"title": "Kleurenschema verwijderd",
"description": "{scheme} succesvol verwijderd"
},
"error": {
"title": "Verwijderen mislukt",
"description": "Verwijderen van {scheme} mislukt"
}
},
"title": "Kleurschema"
},
"control-center": {

View File

@@ -1003,6 +1003,41 @@
}
}
},
"download": {
"button": "Baixar mais",
"title": "Baixar esquemas de cores",
"fetching": "Buscando esquemas de cores disponíveis...",
"empty": "Nenhum esquema de cores disponível",
"refresh": "Atualizar",
"download": "Baixar",
"downloading": "Baixando...",
"delete": "Excluir",
"installed": "Instalado",
"success": {
"title": "Esquema de cores baixado",
"description": "{scheme} baixado com sucesso"
},
"error": {
"title": "Falha no download",
"description": "Falha ao baixar {scheme}",
"invalid-response": "Formato de resposta da API inválido",
"parse-failed": "Falha ao analisar a resposta da API: {error}",
"rate-limit": "Limite de taxa da API do GitHub excedido",
"api-error": "Erro da API: {status}",
"no-files": "Nenhum arquivo encontrado para o esquema",
"download-failed": "Falha no download com código de saída: {code}"
}
},
"delete": {
"success": {
"title": "Esquema de cores excluído",
"description": "{scheme} excluído com sucesso"
},
"error": {
"title": "Falha ao excluir",
"description": "Falha ao excluir {scheme}"
}
},
"title": "Esquema de cores"
},
"control-center": {

View File

@@ -1003,6 +1003,41 @@
}
}
},
"download": {
"button": "Загрузить ещё",
"title": "Загрузить цветовые схемы",
"fetching": "Получение доступных цветовых схем...",
"empty": "Нет доступных цветовых схем",
"refresh": "Обновить",
"download": "Загрузить",
"downloading": "Загрузка...",
"delete": "Удалить",
"installed": "Установлено",
"success": {
"title": "Цветовая схема загружена",
"description": "{scheme} успешно загружена"
},
"error": {
"title": "Ошибка загрузки",
"description": "Не удалось загрузить {scheme}",
"invalid-response": "Неверный формат ответа API",
"parse-failed": "Ошибка парсинга ответа API: {error}",
"rate-limit": "Превышен лимит запросов GitHub API",
"api-error": "Ошибка API: {status}",
"no-files": "Файлы для схемы не найдены",
"download-failed": "Ошибка загрузки с кодом выхода: {code}"
}
},
"delete": {
"success": {
"title": "Цветовая схема удалена",
"description": "{scheme} успешно удалена"
},
"error": {
"title": "Ошибка удаления",
"description": "Не удалось удалить {scheme}"
}
},
"title": "Цветовая схема"
},
"control-center": {

View File

@@ -1003,6 +1003,41 @@
}
}
},
"download": {
"button": "Daha fazla indir",
"title": "Renk şemalarını indir",
"fetching": "Mevcut renk şemaları alınıyor...",
"empty": "Mevcut renk şeması yok",
"refresh": "Yenile",
"download": "İndir",
"downloading": "İndiriliyor...",
"delete": "Sil",
"installed": "Yüklü",
"success": {
"title": "Renk şeması indirildi",
"description": "{scheme} başarıyla indirildi"
},
"error": {
"title": "İndirme başarısız",
"description": "{scheme} indirilemedi",
"invalid-response": "Geçersiz API yanıt formatı",
"parse-failed": "API yanıtı ayrıştırılamadı: {error}",
"rate-limit": "GitHub API hız sınırııldı",
"api-error": "API hatası: {status}",
"no-files": "Şema için dosya bulunamadı",
"download-failed": "İndirme başarısız, çıkış kodu: {code}"
}
},
"delete": {
"success": {
"title": "Renk şeması silindi",
"description": "{scheme} başarıyla silindi"
},
"error": {
"title": "Silme başarısız",
"description": "{scheme} silinemedi"
}
},
"title": "Renk şeması"
},
"control-center": {

View File

@@ -1003,6 +1003,41 @@
}
}
},
"download": {
"button": "Завантажити ще",
"title": "Завантажити кольорові схеми",
"fetching": "Отримання доступних кольорових схем...",
"empty": "Немає доступних кольорових схем",
"refresh": "Оновити",
"download": "Завантажити",
"downloading": "Завантаження...",
"delete": "Видалити",
"installed": "Встановлено",
"success": {
"title": "Кольорову схему завантажено",
"description": "{scheme} успішно завантажено"
},
"error": {
"title": "Помилка завантаження",
"description": "Не вдалося завантажити {scheme}",
"invalid-response": "Невірний формат відповіді API",
"parse-failed": "Помилка парсингу відповіді API: {error}",
"rate-limit": "Перевищено ліміт запитів GitHub API",
"api-error": "Помилка API: {status}",
"no-files": "Файли для схеми не знайдено",
"download-failed": "Помилка завантаження з кодом виходу: {code}"
}
},
"delete": {
"success": {
"title": "Кольорову схему видалено",
"description": "{scheme} успішно видалено"
},
"error": {
"title": "Помилка видалення",
"description": "Не вдалося видалити {scheme}"
}
},
"title": "Колірна схема"
},
"control-center": {

View File

@@ -1003,6 +1003,41 @@
}
}
},
"download": {
"button": "下载更多",
"title": "下载配色方案",
"fetching": "正在获取可用的配色方案...",
"empty": "没有可用的配色方案",
"refresh": "刷新",
"download": "下载",
"downloading": "正在下载...",
"delete": "删除",
"installed": "已安装",
"success": {
"title": "配色方案已下载",
"description": "成功下载 {scheme}"
},
"error": {
"title": "下载失败",
"description": "下载 {scheme} 失败",
"invalid-response": "无效的 API 响应格式",
"parse-failed": "解析 API 响应失败: {error}",
"rate-limit": "GitHub API 速率限制已超出",
"api-error": "API 错误: {status}",
"no-files": "未找到方案的文件",
"download-failed": "下载失败,退出代码: {code}"
}
},
"delete": {
"success": {
"title": "配色方案已删除",
"description": "成功删除 {scheme}"
},
"error": {
"title": "删除失败",
"description": "删除 {scheme} 失败"
}
},
"title": "配色方案"
},
"control-center": {

View File

@@ -5,6 +5,7 @@ import Quickshell
import qs.Commons
import qs.Modules.MainScreen
import qs.Modules.Panels.Settings.Tabs
import qs.Modules.Panels.Settings.Tabs.ColorScheme
import qs.Services.System
import qs.Widgets

View File

@@ -3,6 +3,7 @@ import QtQuick.Controls
import QtQuick.Layouts
import Quickshell
import Quickshell.Io
import "."
import qs.Commons
import qs.Services.System
import qs.Services.Theming
@@ -94,6 +95,11 @@ ColumnLayout {
cacheVersion++;
}
// Function to open download popup
function openDownloadPopup() {
downloadPopupLoader.open();
}
// When the list of available schemes changes, clear the cache
Connections {
target: ColorSchemeService
@@ -326,9 +332,49 @@ ColumnLayout {
Layout.fillWidth: true
visible: !Settings.data.colorSchemes.useWallpaperColors
NHeader {
label: I18n.tr("settings.color-scheme.predefined.section.label")
description: I18n.tr("settings.color-scheme.predefined.section.description")
RowLayout {
Layout.fillWidth: true
NHeader {
label: I18n.tr("settings.color-scheme.predefined.section.label")
description: I18n.tr("settings.color-scheme.predefined.section.description")
Layout.fillWidth: true
}
NButton {
text: I18n.tr("settings.color-scheme.download.button")
icon: "download"
onClicked: {
root.openDownloadPopup();
}
}
}
// Download popup
Loader {
id: downloadPopupLoader
active: false
sourceComponent: SchemeDownloader {
parent: Overlay.overlay
}
property bool pendingOpen: false
function open() {
pendingOpen = true;
active = true;
if (item) {
item.open();
pendingOpen = false;
}
}
onItemChanged: {
if (item && pendingOpen) {
item.open();
pendingOpen = false;
}
}
}
// Color Schemes Grid

View File

@@ -0,0 +1,928 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Quickshell
import Quickshell.Io
import qs.Commons
import qs.Services.Theming
import qs.Services.UI
import qs.Widgets
Popup {
id: root
property var availableSchemes: []
property bool fetching: false
property bool downloading: false
property bool hasInitialData: false // Track if we've loaded data at least once
property string downloadError: ""
property string downloadingScheme: ""
property string pendingApplyScheme: "" // Scheme name to apply after reload
property real lastApiFetchTime: 0 // Track when we last fetched from API to prevent rapid calls
property int minApiFetchInterval: 60 // Minimum seconds between API fetches (1 minute)
// Cache for remote scheme colors
property var schemeColorsCache: ({})
property int cacheVersion: 0
// Cache for available schemes list
property string schemesCacheFile: Settings.cacheDir + "color-schemes-list.json"
property int schemesCacheUpdateFrequency: 2 * 60 * 60 // 2 hours in seconds
// Cache for repo branch info (to reduce API calls during downloads)
property string cachedBranch: "main"
property string cachedBranchSha: ""
width: Math.max(500, contentColumn.implicitWidth + (Style.marginXL * 2))
height: Math.min(800, contentColumn.implicitHeight + (Style.marginXL * 2))
padding: Style.marginXL
modal: true
dim: false
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
anchors.centerIn: parent
// Helper function to get color from cached scheme data
function getSchemeColor(schemeName, colorKey) {
var _ = cacheVersion; // Create dependency
if (schemeColorsCache[schemeName]) {
var entry = schemeColorsCache[schemeName];
var variant = entry;
// Check if scheme has dark/light variants
if (entry.dark || entry.light) {
variant = Settings.data.colorSchemes.darkMode ? (entry.dark || entry.light) : (entry.light || entry.dark);
}
if (variant && variant[colorKey]) {
return variant[colorKey];
}
}
// Return visible defaults while loading
var defaults = {
"mSurface": Color.mSurfaceVariant,
"mPrimary": Color.mPrimary,
"mSecondary": Color.mSecondary,
"mTertiary": Color.mTertiary,
"mError": Color.mError,
"mOnSurface": Color.mOnSurfaceVariant
};
return defaults[colorKey] || Color.mOnSurfaceVariant;
}
// Fetch scheme JSON to get colors for swatches
function fetchSchemeColors(scheme) {
// Skip if already cached
if (schemeColorsCache[scheme.name]) {
return;
}
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.status === 200) {
try {
var jsonData = JSON.parse(xhr.responseText);
schemeColorsCache[scheme.name] = jsonData;
cacheVersion++;
} catch (e) {
Logger.w("ColorSchemeDownload", "Failed to parse scheme JSON for", scheme.name, e);
}
}
}
};
// Try to get the JSON file from the scheme directory
xhr.open("GET", "https://raw.githubusercontent.com/noctalia-dev/noctalia-colorschemes/main/" + scheme.path + "/" + scheme.name + ".json");
xhr.send();
}
// Cache file for schemes list
FileView {
id: schemesCacheFileView
path: schemesCacheFile
printErrors: false
JsonAdapter {
id: schemesCacheAdapter
property var schemes: []
property real timestamp: 0
}
onLoaded: {
loadSchemesFromCache();
}
onLoadFailed: function (error) {
if (error.toString().includes("No such file") || error === 2) {
// Cache doesn't exist, fetch from API (only if popup is open)
if (root.visible) {
Qt.callLater(() => {
fetchAvailableSchemesFromAPI();
});
}
}
}
}
background: Rectangle {
color: Color.mSurface
radius: Style.radiusL
border.color: Color.mPrimary
border.width: Style.borderM
}
function loadSchemesFromCache() {
const now = Time.timestamp;
// Check if cache is expired or missing
if (!schemesCacheAdapter.timestamp || (now >= schemesCacheAdapter.timestamp + schemesCacheUpdateFrequency)) {
// Only fetch from API if we haven't fetched recently (prevent rapid repeated calls)
const timeSinceLastFetch = now - lastApiFetchTime;
if (timeSinceLastFetch >= minApiFetchInterval) {
Logger.d("ColorSchemeDownload", "Cache expired or missing, fetching new schemes");
fetchAvailableSchemesFromAPI();
return;
} else {
// Use cached data even if expired, to avoid rate limits
Logger.d("ColorSchemeDownload", "Cache expired but recent API call detected, using cached data");
if (schemesCacheAdapter.schemes && schemesCacheAdapter.schemes.length > 0) {
availableSchemes = schemesCacheAdapter.schemes;
hasInitialData = true;
fetching = false;
return;
}
}
}
const ageMinutes = Math.round((now - schemesCacheAdapter.timestamp) / 60);
Logger.d("ColorSchemeDownload", "Loading cached schemes (age:", ageMinutes, "minutes)");
if (schemesCacheAdapter.schemes && schemesCacheAdapter.schemes.length > 0) {
availableSchemes = schemesCacheAdapter.schemes;
hasInitialData = true;
fetching = false;
} else {
// Cache is empty, only fetch if we haven't fetched recently
const timeSinceLastFetch = now - lastApiFetchTime;
if (timeSinceLastFetch >= minApiFetchInterval) {
fetchAvailableSchemesFromAPI();
} else {
Logger.d("ColorSchemeDownload", "Cache empty but recent API call detected, skipping fetch");
fetching = false;
}
}
}
function saveSchemesToCache() {
schemesCacheAdapter.schemes = availableSchemes;
schemesCacheAdapter.timestamp = Time.timestamp;
// Ensure cache directory exists
Quickshell.execDetached(["mkdir", "-p", Settings.cacheDir]);
Qt.callLater(() => {
schemesCacheFileView.writeAdapter();
Logger.d("ColorSchemeDownload", "Schemes list saved to cache");
});
}
function fetchAvailableSchemes() {
if (fetching) {
return;
}
// Path is set when popup becomes visible, so FileView will start loading
// Try to load from cache first
if (schemesCacheFileView.loaded) {
loadSchemesFromCache();
} else if (schemesCacheFileView.path) {
// Cache file path is set but not loaded yet, wait for it to load
// The FileView will trigger loadSchemesFromCache() when loaded
// But if it fails, we should fetch from API
if (!schemesCacheFileView.loading) {
schemesCacheFileView.reload();
}
} else {
// No cache file path, fetch directly from API
fetchAvailableSchemesFromAPI();
}
}
function fetchAvailableSchemesFromAPI() {
if (fetching) {
return;
}
// Check if we've fetched recently to prevent rapid repeated calls
const now = Time.timestamp;
const timeSinceLastFetch = now - lastApiFetchTime;
if (timeSinceLastFetch < minApiFetchInterval) {
Logger.d("ColorSchemeDownload", "Skipping API fetch - too soon since last fetch (", Math.round(timeSinceLastFetch), "s ago)");
return;
}
fetching = true;
lastApiFetchTime = now;
// Don't clear availableSchemes immediately to prevent flicker - keep showing old list while fetching
// availableSchemes = [];
downloadError = "";
// Use GitHub API to list contents of the repo
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === XMLHttpRequest.DONE) {
fetching = false;
if (xhr.status === 200) {
try {
var response = JSON.parse(xhr.responseText);
if (Array.isArray(response)) {
// Filter to only directories (type === "dir")
var schemes = [];
for (var i = 0; i < response.length; i++) {
if (response[i].type === "dir") {
schemes.push({
"name": response[i].name,
"path": response[i].path,
"url": response[i].url
});
}
}
availableSchemes = schemes;
hasInitialData = true;
Logger.i("ColorSchemeDownload", "Fetched", schemes.length, "available schemes from API");
// Save to cache
saveSchemesToCache();
} else {
downloadError = I18n.tr("settings.color-scheme.download.error.invalid-response");
Logger.e("ColorSchemeDownload", downloadError);
}
} catch (e) {
downloadError = I18n.tr("settings.color-scheme.download.error.parse-failed", {
"error": e.toString()
});
Logger.e("ColorSchemeDownload", downloadError);
}
} else if (xhr.status === 403) {
// Rate limit hit - try to use cache if available
downloadError = I18n.tr("settings.color-scheme.download.error.rate-limit");
Logger.w("ColorSchemeDownload", downloadError);
if (schemesCacheAdapter.schemes && schemesCacheAdapter.schemes.length > 0) {
availableSchemes = schemesCacheAdapter.schemes;
Logger.i("ColorSchemeDownload", "Using cached schemes due to rate limit");
}
} else {
downloadError = I18n.tr("settings.color-scheme.download.error.api-error", {
"status": xhr.status
});
Logger.e("ColorSchemeDownload", downloadError);
}
}
};
xhr.open("GET", "https://api.github.com/repos/noctalia-dev/noctalia-colorschemes/contents");
xhr.send();
}
function downloadScheme(scheme) {
if (downloading) {
return;
}
downloading = true;
downloadingScheme = scheme.name;
downloadError = "";
Logger.i("ColorSchemeDownload", "Downloading scheme:", scheme.name);
// Use cached branch/SHA if available, otherwise fetch
if (cachedBranchSha) {
// Use cached SHA directly
getSchemeTreeWithSha(scheme, cachedBranch, cachedBranchSha);
} else if (cachedBranch) {
// We have branch name, just need SHA
getSchemeTree(scheme, cachedBranch);
} else {
// Need to fetch branch info first
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.status === 200) {
try {
var repoInfo = JSON.parse(xhr.responseText);
var defaultBranch = repoInfo.default_branch || "main";
cachedBranch = defaultBranch;
// Now get the tree for the scheme directory
getSchemeTree(scheme, defaultBranch);
} catch (e) {
// Fallback: try to get files directly
getSchemeFilesDirect(scheme);
}
} else {
// Fallback: try to get files directly
getSchemeFilesDirect(scheme);
}
}
};
xhr.open("GET", "https://api.github.com/repos/noctalia-dev/noctalia-colorschemes");
xhr.send();
}
}
function getSchemeTree(scheme, branch) {
// First get the SHA of the branch
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.status === 200) {
try {
var refResponse = JSON.parse(xhr.responseText);
var sha = refResponse.object ? refResponse.object.sha : null;
if (sha) {
// Cache the SHA for future downloads
cachedBranchSha = sha;
// Now get the tree
getSchemeTreeWithSha(scheme, branch, sha);
} else {
// Fallback to direct method
getSchemeFilesDirect(scheme);
}
} catch (e) {
// Fallback to direct method
getSchemeFilesDirect(scheme);
}
} else {
// Fallback to direct method
getSchemeFilesDirect(scheme);
}
}
};
xhr.open("GET", "https://api.github.com/repos/noctalia-dev/noctalia-colorschemes/git/refs/heads/" + branch);
xhr.send();
}
function getSchemeTreeWithSha(scheme, branch, sha) {
// Use git trees API to get all files recursively
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.status === 200) {
try {
var response = JSON.parse(xhr.responseText);
if (response.tree && Array.isArray(response.tree)) {
// Filter files that belong to this scheme
var files = [];
for (var i = 0; i < response.tree.length; i++) {
var item = response.tree[i];
if (item.type === "blob" && item.path.startsWith(scheme.path + "/")) {
files.push({
"path": item.path,
"url": "https://raw.githubusercontent.com/noctalia-dev/noctalia-colorschemes/" + branch + "/" + item.path,
"name": item.path.split("/").pop()
});
}
}
downloadSchemeFiles(scheme.name, files);
} else {
// Fallback to direct method
getSchemeFilesDirect(scheme);
}
} catch (e) {
downloadError = I18n.tr("settings.color-scheme.download.error.parse-failed", {
"error": e.toString()
});
downloading = false;
downloadingScheme = "";
Logger.e("ColorSchemeDownload", downloadError);
}
} else {
// Fallback to direct method
getSchemeFilesDirect(scheme);
}
}
};
xhr.open("GET", "https://api.github.com/repos/noctalia-dev/noctalia-colorschemes/git/trees/" + sha + "?recursive=1");
xhr.send();
}
function getSchemeFilesDirect(scheme) {
// Fallback: get files directly using contents API (non-recursive, but works)
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.status === 200) {
try {
var response = JSON.parse(xhr.responseText);
if (Array.isArray(response)) {
// Recursively get all files
getAllFilesRecursive(scheme, response, []);
} else {
downloadError = I18n.tr("settings.color-scheme.download.error.invalid-response");
downloading = false;
downloadingScheme = "";
Logger.e("ColorSchemeDownload", downloadError);
}
} catch (e) {
downloadError = I18n.tr("settings.color-scheme.download.error.parse-failed", {
"error": e.toString()
});
downloading = false;
downloadingScheme = "";
Logger.e("ColorSchemeDownload", downloadError);
}
} else {
downloadError = I18n.tr("settings.color-scheme.download.error.api-error", {
"status": xhr.status
});
downloading = false;
downloadingScheme = "";
Logger.e("ColorSchemeDownload", downloadError);
}
}
};
xhr.open("GET", "https://api.github.com/repos/noctalia-dev/noctalia-colorschemes/contents/" + scheme.path);
xhr.send();
}
function getAllFilesRecursive(scheme, items, allFiles, callback) {
if (!callback) {
callback = function () {
downloadSchemeFiles(scheme.name, allFiles);
};
}
if (items.length === 0) {
callback();
return;
}
var pending = 0;
var completed = 0;
function checkComplete() {
completed++;
if (completed === items.length && pending === 0) {
callback();
}
}
for (var i = 0; i < items.length; i++) {
var item = items[i];
if (item.type === "file") {
allFiles.push({
"path": item.path,
"url": item.download_url,
"name": item.name
});
checkComplete();
} else if (item.type === "dir") {
pending++;
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function (dirItem) {
return function () {
if (xhr.readyState === XMLHttpRequest.DONE) {
pending--;
if (xhr.status === 200) {
try {
var dirResponse = JSON.parse(xhr.responseText);
if (Array.isArray(dirResponse)) {
getAllFilesRecursive(scheme, dirResponse, allFiles, function () {
checkComplete();
});
} else {
checkComplete();
}
} catch (e) {
Logger.e("ColorSchemeDownload", "Failed to parse directory response:", e);
checkComplete();
}
} else {
checkComplete();
}
}
};
}(item);
xhr.open("GET", item.url);
xhr.send();
} else {
checkComplete();
}
}
}
function downloadSchemeFiles(schemeName, files) {
if (files.length === 0) {
downloadError = I18n.tr("settings.color-scheme.download.error.no-files");
downloading = false;
downloadingScheme = "";
Logger.e("ColorSchemeDownload", downloadError);
return;
}
var targetDir = ColorSchemeService.schemesDirectory + "/" + schemeName;
var downloadScript = "mkdir -p '" + targetDir + "'\n";
// Build download script for all files
for (var i = 0; i < files.length; i++) {
var file = files[i];
var filePath = file.path;
// Remove scheme name and leading / from path
var relativePath = filePath;
if (filePath.startsWith(schemeName + "/")) {
relativePath = filePath.substring(schemeName.length + 1);
} else if (filePath.startsWith("/" + schemeName + "/")) {
relativePath = filePath.substring(schemeName.length + 2);
}
var localPath = targetDir + "/" + relativePath;
var localDir = localPath.substring(0, localPath.lastIndexOf('/'));
downloadScript += "mkdir -p '" + localDir + "'\n";
var downloadUrl = file.url || file.download_url;
if (downloadUrl) {
downloadScript += "curl -L -s -o '" + localPath + "' '" + downloadUrl + "' || wget -q -O '" + localPath + "' '" + downloadUrl + "'\n";
}
}
Logger.d("ColorSchemeDownload", "Downloading", files.length, "files for scheme", schemeName);
// Execute download script
var downloadProcess = Qt.createQmlObject(`
import QtQuick
import Quickshell.Io
Process {
id: downloadProcess
command: ["sh", "-c", ` + JSON.stringify(downloadScript) + `]
stderr: StdioCollector {
onStreamFinished: {
if (text && text.trim()) {
Logger.e("ColorSchemeDownload", "Download stderr:", text);
}
}
}
}
`, root, "DownloadProcess_" + schemeName);
downloadProcess.exited.connect(function (exitCode) {
if (exitCode === 0) {
Logger.i("ColorSchemeDownload", "Scheme downloaded successfully:", schemeName);
ToastService.showNotice(I18n.tr("settings.color-scheme.download.success.title"), I18n.tr("settings.color-scheme.download.success.description", {
"scheme": schemeName
}), "settings-color-scheme");
// Set pending scheme to apply after reload
pendingApplyScheme = schemeName;
// Reload color schemes
ColorSchemeService.loadColorSchemes();
downloading = false;
downloadingScheme = "";
} else {
downloadError = I18n.tr("settings.color-scheme.download.error.download-failed", {
"code": exitCode
});
Logger.e("ColorSchemeDownload", downloadError);
ToastService.showError(I18n.tr("settings.color-scheme.download.error.title"), I18n.tr("settings.color-scheme.download.error.description", {
"scheme": schemeName
}));
downloading = false;
downloadingScheme = "";
}
downloadProcess.destroy();
});
downloadProcess.running = true;
}
function isSchemeInstalled(schemeName) {
// Check if scheme already exists in ColorSchemeService
for (var i = 0; i < ColorSchemeService.schemes.length; i++) {
var path = ColorSchemeService.schemes[i];
if (path.indexOf("/" + schemeName + "/") !== -1 || path.indexOf("/" + schemeName + ".json") !== -1) {
return true;
}
}
return false;
}
function deleteScheme(schemeName) {
if (downloading) {
return;
}
Logger.i("ColorSchemeDownload", "Deleting scheme:", schemeName);
// Check if the deleted scheme is the currently active one
var currentScheme = Settings.data.colorSchemes.predefinedScheme || "";
var deletedSchemeDisplayName = ColorSchemeService.getBasename(schemeName);
var needsReset = (currentScheme === deletedSchemeDisplayName);
var targetDir = ColorSchemeService.schemesDirectory + "/" + schemeName;
var deleteScript = "rm -rf '" + targetDir + "'";
var deleteProcess = Qt.createQmlObject(`
import QtQuick
import Quickshell.Io
Process {
id: deleteProcess
command: ["sh", "-c", ` + JSON.stringify(deleteScript) + `]
}
`, root, "DeleteProcess_" + schemeName);
deleteProcess.exited.connect(function (exitCode) {
if (exitCode === 0) {
Logger.i("ColorSchemeDownload", "Scheme deleted successfully:", schemeName);
ToastService.showNotice(I18n.tr("settings.color-scheme.delete.success.title"), I18n.tr("settings.color-scheme.delete.success.description", {
"scheme": schemeName
}), "settings-color-scheme");
// If the deleted scheme was the active one, reset to default BEFORE reloading
if (needsReset) {
Logger.i("ColorSchemeDownload", "Deleted scheme was active, resetting to Noctalia (default)");
// Clear the setting immediately so ColorSchemeService won't try to apply the deleted scheme
Settings.data.colorSchemes.predefinedScheme = "Noctalia (default)";
// Apply the default scheme immediately
ColorSchemeService.setPredefinedScheme("Noctalia (default)");
}
// Reload color schemes
ColorSchemeService.loadColorSchemes();
} else {
Logger.e("ColorSchemeDownload", "Delete failed with exit code:", exitCode);
ToastService.showError(I18n.tr("settings.color-scheme.delete.error.title"), I18n.tr("settings.color-scheme.delete.error.description", {
"scheme": schemeName
}));
}
deleteProcess.destroy();
});
deleteProcess.running = true;
}
Connections {
target: ColorSchemeService
function onScanningChanged() {
// When scanning completes and we have a pending scheme, apply it
if (!ColorSchemeService.scanning && pendingApplyScheme !== "") {
var schemeToApply = pendingApplyScheme;
pendingApplyScheme = ""; // Clear pending before applying
// Wait a tiny bit to ensure schemes array is updated
applyTimer.schemeName = schemeToApply;
applyTimer.restart();
}
}
}
Timer {
id: applyTimer
property string schemeName: ""
interval: 100 // Small delay to ensure schemes array is populated
onTriggered: {
if (schemeName !== "") {
Logger.i("ColorSchemeDownload", "Auto-applying downloaded scheme:", schemeName);
// Use setPredefinedScheme which will apply and set it as the current scheme
ColorSchemeService.setPredefinedScheme(schemeName);
schemeName = "";
}
}
}
onOpened: {
fetchAvailableSchemes();
}
function preFetchSchemeColors() {
if (availableSchemes.length > 0 && visible) {
Qt.callLater(function () {
for (var i = 0; i < availableSchemes.length; i++) {
var scheme = availableSchemes[i];
if (!schemeColorsCache[scheme.name]) {
fetchSchemeColors(scheme);
}
}
});
}
}
onAvailableSchemesChanged: preFetchSchemeColors()
onVisibleChanged: preFetchSchemeColors()
contentItem: ColumnLayout {
id: contentColumn
width: parent.width
spacing: Style.marginL
// Header
RowLayout {
Layout.fillWidth: true
NText {
text: I18n.tr("settings.color-scheme.download.title")
pointSize: Style.fontSizeL
font.weight: Style.fontWeightBold
color: Color.mPrimary
Layout.fillWidth: true
}
NIconButton {
icon: "refresh"
tooltipText: I18n.tr("settings.color-scheme.download.refresh")
enabled: !fetching && !downloading
onClicked: {
// Force refresh by clearing cache timestamp and fetching directly from API
schemesCacheAdapter.timestamp = 0;
// Fetch directly from API to avoid cache check delay
fetchAvailableSchemesFromAPI();
}
}
NIconButton {
icon: "close"
tooltipText: I18n.tr("tooltips.close")
onClicked: root.close()
}
}
// Separator
Rectangle {
Layout.fillWidth: true
Layout.preferredHeight: 1
color: Color.mOutline
}
// Error message
Rectangle {
Layout.fillWidth: true
Layout.preferredHeight: errorText.implicitHeight + Style.marginM
visible: downloadError !== ""
color: Color.mError
radius: Style.radiusS
NText {
id: errorText
anchors.fill: parent
anchors.margins: Style.marginM
text: downloadError
pointSize: Style.fontSizeS
color: Color.mOnError
wrapMode: Text.WordWrap
}
}
// Loading indicator - only show on initial load, not during refresh
RowLayout {
Layout.fillWidth: true
visible: fetching && !hasInitialData
spacing: Style.marginM
NBusyIndicator {
Layout.preferredWidth: 20
Layout.preferredHeight: 20
}
NText {
text: I18n.tr("settings.color-scheme.download.fetching")
pointSize: Style.fontSizeM
color: Color.mOnSurfaceVariant
}
}
// Schemes list - keep visible during refresh to prevent flicker
NScrollView {
id: schemesScrollView
Layout.fillWidth: true
Layout.preferredHeight: 400
visible: hasInitialData && availableSchemes.length > 0
verticalPolicy: ScrollBar.AsNeeded
horizontalPolicy: ScrollBar.AlwaysOff
// Only show scrollbar when content actually overflows (size < 1.0 means content is larger than viewport)
ScrollBar.vertical.visible: schemesScrollView.ScrollBar.vertical.size < 1.0
ColumnLayout {
width: {
// Always account for scrollbar width when it's visible (for testing with visible: true)
var scrollbarWidth = schemesScrollView.ScrollBar.vertical.visible ? (schemesScrollView.handleWidth + Style.marginS) : 0;
return parent.width - scrollbarWidth;
}
spacing: Style.marginS
Repeater {
model: availableSchemes
Rectangle {
Layout.fillWidth: true
Layout.preferredHeight: 50 * Style.uiScaleRatio
radius: Style.radiusS
property string schemeName: modelData.name
color: root.getSchemeColor(schemeName, "mSurfaceVariant")
border.width: Style.borderS
border.color: Color.mOutline
Behavior on color {
ColorAnimation {
duration: Style.animationFast
easing.type: Easing.InOutCubic
}
}
Component.onCompleted: {
if (root.visible && !root.schemeColorsCache[schemeName]) {
root.fetchSchemeColors(modelData);
}
}
RowLayout {
id: schemeRow
anchors.left: parent.left
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: Style.marginL
anchors.rightMargin: Style.marginL
spacing: Style.marginS
property string schemeName: modelData.name
property int diameter: 16 * Style.uiScaleRatio
property var colorKeys: ["mPrimary", "mSecondary", "mTertiary", "mError"]
NText {
text: schemeRow.schemeName
pointSize: Style.fontSizeS
color: root.getSchemeColor(schemeRow.schemeName, "mOnSurface")
Layout.fillWidth: true
elide: Text.ElideRight
Layout.alignment: Qt.AlignVCenter
Behavior on color {
ColorAnimation {
duration: Style.animationFast
easing.type: Easing.InOutCubic
}
}
}
// Color swatches
Repeater {
model: schemeRow.colorKeys
Rectangle {
width: schemeRow.diameter
height: schemeRow.diameter
radius: schemeRow.diameter * 0.5
color: root.getSchemeColor(schemeRow.schemeName, modelData)
Layout.alignment: Qt.AlignVCenter
Behavior on color {
ColorAnimation {
duration: Style.animationFast
easing.type: Easing.InOutCubic
}
}
}
}
// Download/Delete button
NIconButton {
property bool isDownloading: downloading && downloadingScheme === schemeRow.schemeName
property bool isInstalled: root.isSchemeInstalled(schemeRow.schemeName)
icon: isDownloading ? "" : (isInstalled ? "trash" : "download")
tooltipText: isDownloading ? I18n.tr("settings.color-scheme.download.downloading") : (isInstalled ? I18n.tr("settings.color-scheme.download.delete") : I18n.tr("settings.color-scheme.download.download"))
enabled: !downloading
Layout.alignment: Qt.AlignVCenter
onClicked: isInstalled ? root.deleteScheme(schemeRow.schemeName) : root.downloadScheme(modelData)
NBusyIndicator {
anchors.centerIn: parent
width: 16 * Style.uiScaleRatio
height: 16 * Style.uiScaleRatio
visible: parent.isDownloading
}
}
}
}
}
}
}
// Empty state
ColumnLayout {
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
spacing: Style.marginM
visible: !fetching && availableSchemes.length === 0 && downloadError === ""
NIcon {
icon: "package"
pointSize: 48
color: Color.mOnSurfaceVariant
Layout.alignment: Qt.AlignHCenter
}
NText {
text: I18n.tr("settings.color-scheme.download.empty")
pointSize: Style.fontSizeM
color: Color.mOnSurfaceVariant
Layout.alignment: Qt.AlignHCenter
}
}
}
}