release: prepare Twitch VOD Manager 1.0.2

Redesign the seven-area desktop workspace with responsive navigation, searchable settings, localized controls, and accessible update states.

Harden Electron release coverage with fully isolated user data, download paths, offline fixtures, concurrency checks, and public-release manifest validation.
This commit is contained in:
Sucukdeluxe
2026-08-10 12:29:56 +02:00
parent dacd66fe1c
commit d599593966
29 changed files with 2388 additions and 725 deletions
+376 -31
View File
@@ -17,6 +17,12 @@
--workspace-warning: #f2c66d;
--workspace-danger: #ef7d7d;
--workspace-info: #8fb5ff;
--workspace-empty-icon: #f3f3f3;
--workspace-popover-bg: #4f4d4d;
--workspace-popover-border: #5b5959;
--workspace-popover-text: #ffffff;
--workspace-popover-muted: #e4e2e2;
--workspace-focus-ring: #ffffff;
--workspace-radius: 6px;
--workspace-radius-small: 4px;
--workspace-topbar-height: 40px;
@@ -61,6 +67,12 @@ body.theme-system {
--workspace-warning: #f2c66d;
--workspace-danger: #ef7d7d;
--workspace-info: #8fb5ff;
--workspace-empty-icon: #f3f3f3;
--workspace-popover-bg: #4f4d4d;
--workspace-popover-border: #5b5959;
--workspace-popover-text: #ffffff;
--workspace-popover-muted: #e4e2e2;
--workspace-focus-ring: #ffffff;
--bg-main: var(--workspace-client);
--bg-sidebar: var(--workspace-panel);
--bg-card: var(--workspace-panel-raised);
@@ -95,6 +107,12 @@ body.theme-light {
--workspace-warning: #8f5d12;
--workspace-danger: #a33d3d;
--workspace-info: #315ea8;
--workspace-empty-icon: #596475;
--workspace-popover-bg: #4f4d4d;
--workspace-popover-border: #5b5959;
--workspace-popover-text: #ffffff;
--workspace-popover-muted: #e4e2e2;
--workspace-focus-ring: #172033;
--bg-main: var(--workspace-client);
--bg-sidebar: var(--workspace-panel);
--bg-card: var(--workspace-panel-raised);
@@ -217,7 +235,7 @@ textarea:disabled,
height: 19px;
flex: 0 0 19px;
color: var(--workspace-primary);
fill: currentColor;
fill: none;
}
.topbar-brand-name {
@@ -266,29 +284,31 @@ textarea:disabled,
}
.top-nav-item.nav-item.active {
color: var(--workspace-primary);
background: var(--workspace-control);
border-color: var(--workspace-border-strong);
color: var(--workspace-primary-text);
background: var(--workspace-primary);
border-color: var(--workspace-primary);
}
.top-nav-item.nav-item svg {
width: 17px;
height: 17px;
flex: 0 0 17px;
fill: currentColor;
fill: none;
stroke: currentColor;
}
.top-nav-item .top-nav-label,
.top-nav-item.nav-item > span {
position: absolute;
width: 1px;
height: 1px;
position: static;
width: auto;
min-width: 0;
height: auto;
padding: 0;
margin: -1px;
margin: 0;
overflow: hidden;
clip: rect(0, 0, 0, 0);
clip: auto;
white-space: nowrap;
text-overflow: ellipsis;
border: 0;
}
@@ -385,9 +405,9 @@ textarea:disabled,
width: max-content;
max-width: 250px;
padding: 7px 9px;
color: var(--workspace-text);
background: #505050;
border: 1px solid #5c5c5c;
color: var(--workspace-popover-text);
background: var(--workspace-popover-bg);
border: 1px solid var(--workspace-popover-border);
border-radius: var(--workspace-radius-small);
font-size: 12px;
font-weight: 600;
@@ -444,7 +464,7 @@ textarea:disabled,
}
.context-panel {
display: none;
display: flex;
width: 100%;
min-width: 0;
min-height: 0;
@@ -453,10 +473,6 @@ textarea:disabled,
overflow: hidden;
}
.context-panel.active {
display: flex;
}
.context-sidebar-header {
display: flex;
flex: 0 0 auto;
@@ -1612,7 +1628,7 @@ input[type="range"] {
width: 56px;
height: 56px;
margin-bottom: 6px;
color: #f3f3f3;
color: var(--workspace-empty-icon);
opacity: 0.92;
}
@@ -2128,6 +2144,12 @@ input[type="range"] {
--workspace-warning: #8f5d12;
--workspace-danger: #a33d3d;
--workspace-info: #315ea8;
--workspace-empty-icon: #596475;
--workspace-popover-bg: #4f4d4d;
--workspace-popover-border: #5b5959;
--workspace-popover-text: #ffffff;
--workspace-popover-muted: #e4e2e2;
--workspace-focus-ring: #172033;
--bg-main: var(--workspace-client);
--bg-sidebar: var(--workspace-panel);
--bg-card: var(--workspace-panel-raised);
@@ -2333,9 +2355,9 @@ input[type="range"] {
align-items: stretch;
gap: 7px;
padding: 8px;
color: var(--workspace-text);
background: #4f4d4d;
border: 1px solid #5b5959;
color: var(--workspace-popover-text);
background: var(--workspace-popover-bg);
border: 1px solid var(--workspace-popover-border);
border-radius: 5px;
font-size: 13px;
font-weight: 600;
@@ -2351,15 +2373,15 @@ input[type="range"] {
right: 39px;
width: 9px;
height: 9px;
background: #4f4d4d;
border-top: 1px solid #5b5959;
border-left: 1px solid #5b5959;
background: var(--workspace-popover-bg);
border-top: 1px solid var(--workspace-popover-border);
border-left: 1px solid var(--workspace-popover-border);
content: "";
transform: rotate(45deg);
}
.workspace-update:hover .workspace-update-popover,
.workspace-update:focus-within .workspace-update-popover {
.workspace-update.show:not(.popover-dismissed):hover .workspace-update-popover,
.workspace-update.show:not(.popover-dismissed):focus-within .workspace-update-popover {
visibility: visible;
opacity: 1;
pointer-events: auto;
@@ -2398,10 +2420,6 @@ input[type="range"] {
height: 5px;
}
.context-panel {
display: flex;
}
.context-switcher {
display: flex;
flex: 0 0 auto;
@@ -2859,3 +2877,330 @@ input[type="range"] {
flex-basis: 190px;
}
}
.top-nav-item.nav-item.active:hover {
color: var(--workspace-primary-text);
background: var(--workspace-primary-hover);
border-color: var(--workspace-primary-hover);
}
.top-nav .top-nav-item:focus-visible {
outline: 2px solid var(--workspace-focus-ring);
outline-offset: 2px;
box-shadow: none;
}
#settingsTab .settings-card:has(#downloadPath) {
width: min(720px, 100%);
}
#settingsTab .form-row:has(#downloadPath) {
display: grid;
grid-template-columns: minmax(0, 1fr) auto auto;
align-items: center;
gap: 8px;
}
#settingsTab #downloadPath {
width: 100%;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
#clipsTab.active {
display: grid;
grid-template-columns: minmax(420px, 1.35fr) minmax(280px, 0.65fr);
align-content: start;
align-items: start;
gap: 16px;
}
#clipsTab .clip-input {
display: grid;
width: 100%;
max-width: none;
grid-template-columns: minmax(0, 1fr) auto;
align-items: center;
gap: 10px;
margin: 0;
padding: 16px;
text-align: left;
background: var(--workspace-panel-raised);
border: 1px solid var(--workspace-border);
border-radius: var(--workspace-radius);
}
#clipsTab .clip-input h2 {
grid-column: 1 / -1;
margin: 0 0 2px;
font-size: 16px;
line-height: 22px;
}
#clipsTab .clip-input #clipUrl {
width: 100%;
min-width: 0;
min-height: 38px;
margin: 0;
}
#clipsTab .clip-input #btnClip {
min-height: 38px;
white-space: nowrap;
}
#clipsTab .clip-input #clipStatus {
grid-column: 1 / -1;
min-height: 20px;
margin: 0;
font-size: 12px;
line-height: 20px;
}
#clipsTab > .settings-card.centered {
width: 100%;
max-width: none;
align-self: start;
margin: 0;
}
.workspace-settings-search {
position: relative;
display: flex;
flex: 0 1 550px;
min-width: 180px;
height: 36px;
align-items: center;
margin-left: auto;
}
.workspace-toolbar .toolbar-context[data-toolbar-for="settings"] {
flex: 1 1 auto;
width: 100%;
}
.workspace-settings-search input {
width: 100%;
min-width: 0;
height: 36px;
padding: 0 36px 0 34px;
color: var(--workspace-text);
background: var(--workspace-control);
border: 1px solid var(--workspace-border);
border-radius: var(--workspace-radius-small);
transition: border-color 120ms ease, box-shadow 120ms ease;
}
.workspace-settings-search > svg {
position: absolute;
left: 11px;
z-index: 1;
width: 14px;
height: 14px;
color: var(--workspace-text-muted);
fill: none;
stroke: currentColor;
pointer-events: none;
}
.workspace-settings-search > button {
position: absolute;
right: 4px;
display: inline-flex;
width: 28px;
height: 28px;
align-items: center;
justify-content: center;
padding: 0;
color: var(--workspace-text-muted);
background: transparent;
border: 0;
border-radius: var(--workspace-radius-small);
cursor: pointer;
}
.workspace-settings-search > button:hover {
color: var(--workspace-text);
background: var(--workspace-control-hover);
}
.workspace-update-popover {
width: 260px;
}
.workspace-update-popover-header {
position: relative;
z-index: 1;
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 10px;
color: var(--workspace-popover-text);
}
.workspace-update-popover-header #updateText {
flex: 1 1 auto;
min-width: 0;
}
#workspaceUpdateDismiss {
display: inline-flex;
width: 24px;
min-width: 24px;
height: 24px;
align-items: center;
justify-content: center;
padding: 0;
color: var(--workspace-popover-muted);
background: transparent;
border: 1px solid transparent;
border-radius: var(--workspace-radius-small);
cursor: pointer;
}
#workspaceUpdateDismiss:hover {
color: var(--workspace-popover-text);
background: rgba(255, 255, 255, 0.12);
border-color: rgba(255, 255, 255, 0.18);
}
#workspaceUpdateDismiss::before {
content: "\00d7";
font-size: 17px;
font-weight: 500;
line-height: 1;
}
.workspace-update-popover-actions {
position: relative;
z-index: 1;
display: flex;
align-items: center;
justify-content: flex-end;
gap: 6px;
}
.workspace-update-popover-actions #updateButton {
flex: 1 1 auto;
}
#workspaceUpdateLater {
display: inline-flex;
min-height: 30px;
align-items: center;
justify-content: center;
padding: 0 9px;
color: var(--workspace-popover-text);
background: transparent;
border: 1px solid var(--workspace-popover-muted);
border-radius: var(--workspace-radius-small);
font-size: 11px;
font-weight: 600;
cursor: pointer;
}
#workspaceUpdateLater:hover {
background: rgba(255, 255, 255, 0.12);
}
.workspace-update-popover .update-banner-progress-track {
background: rgba(255, 255, 255, 0.22);
}
@media (min-width: 1180px) {
.topbar-navigation-cluster {
flex: 0 1 1000px;
width: 1000px;
max-width: calc(100vw - 254px);
}
.topbar-navigation-cluster .topbar-brand {
flex-basis: 190px;
min-width: 190px;
padding: 0 12px;
}
.topbar-navigation-cluster .topbar-brand #logoText {
position: static;
width: auto;
height: auto;
padding: 0;
margin: 0;
overflow: hidden;
clip: auto;
white-space: nowrap;
text-overflow: ellipsis;
border: 0;
}
.topbar-navigation-cluster .top-nav {
min-width: 0;
overflow: hidden;
}
.topbar-navigation-cluster .top-nav-item.nav-item {
flex: 1 1 auto;
width: auto;
min-width: 44px;
max-width: none;
padding: 0 8px;
gap: 6px;
}
.topbar-navigation-cluster .top-nav-item .top-nav-label,
.topbar-navigation-cluster .top-nav-item.nav-item > span {
position: static;
display: block;
width: auto;
min-width: 0;
height: auto;
padding: 0;
margin: 0;
overflow: hidden;
clip: auto;
white-space: nowrap;
text-overflow: ellipsis;
border: 0;
font-size: 12px;
}
}
@media (max-width: 1179px) {
.topbar-navigation-cluster .top-nav-item .top-nav-label,
.topbar-navigation-cluster .top-nav-item.nav-item > span {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
.topbar-navigation-cluster .top-nav-item.nav-item {
width: 44px;
min-width: 44px;
padding: 0;
gap: 0;
}
}
@media (max-width: 1350px) {
.workspace-settings-search {
flex-basis: 280px;
}
}
@media (max-width: 820px) {
#clipsTab.active {
grid-template-columns: minmax(0, 1fr);
}
#settingsTab .form-row:has(#downloadPath) {
grid-template-columns: minmax(0, 1fr);
}
}