Bootstrap saved state from ProxiFyre config

This commit is contained in:
2026-07-08 10:34:40 +03:00
parent c5120669d2
commit e745633d91
6 changed files with 364 additions and 25 deletions

View File

@@ -1050,7 +1050,7 @@ export function App() {
<span>{items.length}</span>
</div>
<div className="apps-config-actions">
{renderApplyActions('proxifyre', { showConfigPath: false })}
{renderApplyActions('proxifyre', { showConfigPath: false, showState: false })}
</div>
</div>
@@ -1158,9 +1158,10 @@ export function App() {
function renderApplyActions(
context: 'proxifyre' | 'proxy',
options: { showConfigPath?: boolean } = {},
options: { showConfigPath?: boolean; showState?: boolean } = {},
) {
const showConfigPath = options.showConfigPath ?? true;
const showState = options.showState ?? true;
const externalProxyError = routeMode === 'external' ? safeProxyError(proxyInput) : null;
const readiness = getApplyReadiness({
routeMode,
@@ -1173,15 +1174,18 @@ export function App() {
busy: isApplying || Boolean(serviceAction) || Boolean(singBoxAction),
});
const showBlocker = !readiness.ready && !isLoading && !isDetectingComponents;
const disabledReason = !readiness.ready && readiness.title && readiness.text
? `${readiness.title}. ${readiness.text}`
: undefined;
return (
<>
{showBlocker ? (
{showState && showBlocker ? (
<div className="apply-state blocked" role="status">
<strong>{readiness.title}</strong>
<span>{readiness.text}</span>
</div>
) : hasUnappliedChanges ? (
) : showState && hasUnappliedChanges ? (
<div className="apply-state pending" role="status">
<strong>Изменения еще не применены в ProxiFyre</strong>
<span>{applyStateText(routeMode, isSingBoxInstalled, Boolean(singbox?.running))}</span>
@@ -1197,6 +1201,7 @@ export function App() {
disabled={!readiness.ready}
loading={isApplying}
loadingLabel={applyButtonLabel(context, true, hasUnappliedChanges, singBoxAction)}
title={disabledReason}
>
{applyButtonLabel(context, isApplying, hasUnappliedChanges, singBoxAction)}
</Button>

View File

@@ -188,9 +188,11 @@ button:disabled {
}
.ui-icon-button {
position: relative;
width: 42px;
min-width: 42px;
min-height: 38px;
overflow: visible;
padding: 0;
}
@@ -1889,6 +1891,8 @@ button.summary-card:hover {
background: #182033;
}
.ui-icon-button[data-tooltip]::before,
.ui-icon-button[data-tooltip]::after,
.add-tile[data-tooltip]::before,
.add-tile[data-tooltip]::after {
position: absolute;
@@ -1896,10 +1900,13 @@ button.summary-card:hover {
z-index: 30;
pointer-events: none;
opacity: 0;
transition: opacity 90ms ease, transform 120ms ease;
transition:
opacity 90ms var(--ease-out),
transform var(--motion-fast) var(--ease-out);
transition-delay: 55ms;
}
.ui-icon-button[data-tooltip]::before,
.add-tile[data-tooltip]::before {
bottom: calc(100% + 3px);
width: 8px;
@@ -1911,6 +1918,7 @@ button.summary-card:hover {
transform: translate(-50%, 2px) rotate(45deg);
}
.ui-icon-button[data-tooltip]::after,
.add-tile[data-tooltip]::after {
bottom: calc(100% + 8px);
border: 1px solid #334155;
@@ -1927,6 +1935,10 @@ button.summary-card:hover {
white-space: nowrap;
}
.ui-icon-button[data-tooltip]:hover::before,
.ui-icon-button[data-tooltip]:hover::after,
.ui-icon-button[data-tooltip]:focus-visible::before,
.ui-icon-button[data-tooltip]:focus-visible::after,
.add-tile[data-tooltip]:hover::before,
.add-tile[data-tooltip]:hover::after,
.add-tile[data-tooltip]:focus-visible::before,
@@ -1934,11 +1946,15 @@ button.summary-card:hover {
opacity: 1;
}
.ui-icon-button[data-tooltip]:hover::before,
.ui-icon-button[data-tooltip]:focus-visible::before,
.add-tile[data-tooltip]:hover::before,
.add-tile[data-tooltip]:focus-visible::before {
transform: translate(-50%, 0) rotate(45deg);
}
.ui-icon-button[data-tooltip]:hover::after,
.ui-icon-button[data-tooltip]:focus-visible::after,
.add-tile[data-tooltip]:hover::after,
.add-tile[data-tooltip]:focus-visible::after {
transform: translate(-50%, 0);
@@ -2058,8 +2074,7 @@ button.summary-card:hover {
flex: 0 0 auto;
}
.app-row,
.empty-state {
.app-row {
border: 1px solid #2b3342;
border-radius: 4px;
background: #131720;
@@ -2072,7 +2087,8 @@ button.summary-card:hover {
.empty-state {
color: #8d99ae;
min-height: 48px;
min-height: 30px;
padding: 6px 2px 2px;
}
.list-skeleton {
@@ -2551,6 +2567,7 @@ button.summary-card:hover {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
.add-toolbar .ui-icon-button,
.add-tile {
width: 100%;
}

View File

@@ -19,6 +19,7 @@ export function IconButton({
title,
...props
}: IconButtonProps) {
const tooltip = title === '' ? undefined : title ?? label;
const classes = [
'ui-icon-button',
`ui-icon-button--${variant}`,
@@ -32,7 +33,7 @@ export function IconButton({
type={props.type ?? 'button'}
className={classes}
aria-label={label}
title={title ?? label}
data-tooltip={tooltip}
disabled={disabled || loading}
>
{loading ? <span className="ui-button-spinner" aria-hidden="true" /> : icon}