chore: compact traffic cards
This commit is contained in:
@@ -12,6 +12,7 @@ export {
|
|||||||
ChevronRight,
|
ChevronRight,
|
||||||
ChevronsUpDown,
|
ChevronsUpDown,
|
||||||
Circle,
|
Circle,
|
||||||
|
CircleQuestionMark,
|
||||||
CircleX,
|
CircleX,
|
||||||
Coins,
|
Coins,
|
||||||
Copy,
|
Copy,
|
||||||
|
|||||||
@@ -360,6 +360,58 @@ a {
|
|||||||
font-weight: 850;
|
font-weight: 850;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.traffic-card-compact {
|
||||||
|
display: grid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.traffic-card-compact .progress {
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.traffic-summary-row {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: minmax(0, 1fr) auto;
|
||||||
|
align-items: baseline;
|
||||||
|
gap: 8px;
|
||||||
|
min-width: 0;
|
||||||
|
line-height: 1.15;
|
||||||
|
}
|
||||||
|
|
||||||
|
.traffic-summary-left,
|
||||||
|
.traffic-summary-right {
|
||||||
|
align-items: baseline;
|
||||||
|
min-width: 0;
|
||||||
|
gap: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.traffic-summary-left {
|
||||||
|
display: block;
|
||||||
|
overflow: hidden;
|
||||||
|
color: var(--muted);
|
||||||
|
font-size: 11px;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.traffic-summary-right {
|
||||||
|
display: inline-flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
color: var(--text);
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 850;
|
||||||
|
text-align: right;
|
||||||
|
white-space: nowrap;
|
||||||
|
font-variant-numeric: tabular-nums;
|
||||||
|
}
|
||||||
|
|
||||||
|
.traffic-summary-separator {
|
||||||
|
color: color-mix(in srgb, var(--muted) 58%, transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.traffic-summary-right .traffic-summary-separator {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
.card-heading {
|
.card-heading {
|
||||||
margin: 0 0 10px;
|
margin: 0 0 10px;
|
||||||
color: var(--text);
|
color: var(--text);
|
||||||
@@ -412,6 +464,9 @@ a {
|
|||||||
|
|
||||||
.traffic-card-depleted .traffic-top span,
|
.traffic-card-depleted .traffic-top span,
|
||||||
.traffic-card-depleted .traffic-top strong,
|
.traffic-card-depleted .traffic-top strong,
|
||||||
|
.traffic-card-depleted .traffic-summary-left,
|
||||||
|
.traffic-card-depleted .traffic-summary-right,
|
||||||
|
.traffic-card-depleted .traffic-summary-separator,
|
||||||
.traffic-card-depleted .traffic-meta,
|
.traffic-card-depleted .traffic-meta,
|
||||||
.traffic-card-depleted .traffic-percent {
|
.traffic-card-depleted .traffic-percent {
|
||||||
color: var(--danger-text);
|
color: var(--danger-text);
|
||||||
@@ -456,6 +511,7 @@ a {
|
|||||||
|
|
||||||
.premium-traffic-meta {
|
.premium-traffic-meta {
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
|
margin-top: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.premium-server-dropdown {
|
.premium-server-dropdown {
|
||||||
@@ -464,23 +520,57 @@ a {
|
|||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.premium-server-dropdown summary {
|
.premium-server-dropdown-inline {
|
||||||
display: inline-flex;
|
display: grid;
|
||||||
align-items: center;
|
|
||||||
gap: 6px;
|
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
min-height: 32px;
|
}
|
||||||
margin: -6px -8px;
|
|
||||||
padding: 6px 8px;
|
.premium-server-dropdown summary {
|
||||||
|
min-width: 0;
|
||||||
|
min-height: 26px;
|
||||||
|
margin: -4px -7px 0;
|
||||||
|
padding: 4px 7px;
|
||||||
|
border-radius: 999px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
-webkit-tap-highlight-color: transparent;
|
-webkit-tap-highlight-color: transparent;
|
||||||
|
transition:
|
||||||
|
background 0.16s ease,
|
||||||
|
color 0.16s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.premium-server-dropdown-inline summary {
|
||||||
|
display: grid;
|
||||||
|
max-width: 100%;
|
||||||
|
min-height: 0;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.premium-server-summary {
|
||||||
|
grid-template-columns: minmax(0, 1fr) auto;
|
||||||
|
align-items: baseline;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.premium-summary-trigger {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
min-width: 0;
|
||||||
|
gap: 6px;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.premium-server-dropdown summary:focus {
|
.premium-server-dropdown summary:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.premium-server-dropdown summary:focus-visible {
|
||||||
|
background: color-mix(in srgb, var(--accent) 12%, transparent);
|
||||||
|
box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 22%, transparent);
|
||||||
|
}
|
||||||
|
|
||||||
.premium-server-dropdown summary::-webkit-details-marker {
|
.premium-server-dropdown summary::-webkit-details-marker {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
@@ -491,13 +581,64 @@ a {
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.premium-summary-copy {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.premium-summary-copy {
|
||||||
|
flex: 0 1 auto;
|
||||||
|
min-width: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
.premium-server-dropdown svg {
|
.premium-server-dropdown svg {
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
opacity: 0.72;
|
opacity: 0.82;
|
||||||
|
}
|
||||||
|
|
||||||
|
.premium-server-help-icon {
|
||||||
|
padding: 1px;
|
||||||
|
border-radius: 999px;
|
||||||
|
color: var(--muted);
|
||||||
|
background: color-mix(in srgb, var(--muted) 10%, transparent);
|
||||||
|
transition:
|
||||||
|
color 0.16s ease,
|
||||||
|
background 0.16s ease,
|
||||||
|
transform 0.18s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.premium-server-dropdown summary:hover .premium-server-help-icon,
|
||||||
|
.premium-server-dropdown[open] .premium-server-help-icon {
|
||||||
|
color: var(--accent);
|
||||||
|
background: color-mix(in srgb, var(--accent) 14%, transparent);
|
||||||
}
|
}
|
||||||
|
|
||||||
.premium-server-list-dropdown {
|
.premium-server-list-dropdown {
|
||||||
margin-top: 8px;
|
display: grid;
|
||||||
|
grid-template-rows: 0fr;
|
||||||
|
margin-top: 0;
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-2px);
|
||||||
|
transform-origin: top;
|
||||||
|
transition:
|
||||||
|
grid-template-rows 0.22s ease,
|
||||||
|
margin-top 0.22s ease,
|
||||||
|
opacity 0.18s ease,
|
||||||
|
transform 0.22s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.premium-server-dropdown[open] .premium-server-list-dropdown {
|
||||||
|
grid-template-rows: 1fr;
|
||||||
|
margin-top: 6px;
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.premium-server-list-dropdown > div {
|
||||||
|
min-height: 0;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.premium-detail-grid {
|
.premium-detail-grid {
|
||||||
@@ -2466,6 +2607,15 @@ a {
|
|||||||
--screen-gutter: 10px;
|
--screen-gutter: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.traffic-summary-row {
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.traffic-summary-left,
|
||||||
|
.traffic-summary-right {
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
.period-grid,
|
.period-grid,
|
||||||
.method-grid {
|
.method-grid {
|
||||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
@@ -2496,6 +2646,12 @@ a {
|
|||||||
.motion-height-stage.motion-height-locked {
|
.motion-height-stage.motion-height-locked {
|
||||||
transition: none !important;
|
transition: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.premium-server-dropdown summary,
|
||||||
|
.premium-server-help-icon,
|
||||||
|
.premium-server-list-dropdown {
|
||||||
|
transition: none !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@supports not (color: color-mix(in srgb, #000 50%, #fff)) {
|
@supports not (color: color-mix(in srgb, #000 50%, #fff)) {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import {
|
import {
|
||||||
CheckCircle2,
|
CheckCircle2,
|
||||||
ChevronsUpDown,
|
CircleQuestionMark,
|
||||||
CircleX,
|
CircleX,
|
||||||
CreditCard,
|
CreditCard,
|
||||||
Database,
|
Database,
|
||||||
@@ -58,6 +58,7 @@
|
|||||||
}
|
}
|
||||||
function regularTrafficCardClass(sub = subscription) {
|
function regularTrafficCardClass(sub = subscription) {
|
||||||
return [
|
return [
|
||||||
|
"traffic-card-compact",
|
||||||
regularTrafficTopupBarClickable ? "traffic-card-clickable" : "",
|
regularTrafficTopupBarClickable ? "traffic-card-clickable" : "",
|
||||||
regularTrafficDepleted(sub) ? "traffic-card-depleted" : "",
|
regularTrafficDepleted(sub) ? "traffic-card-depleted" : "",
|
||||||
]
|
]
|
||||||
@@ -79,6 +80,11 @@
|
|||||||
function premiumTitle(sub = subscription) {
|
function premiumTitle(sub = subscription) {
|
||||||
return premiumTitleFn(sub, t);
|
return premiumTitleFn(sub, t);
|
||||||
}
|
}
|
||||||
|
function premiumTrafficMetaLabel(sub = subscription) {
|
||||||
|
return sub?.premium_is_limited
|
||||||
|
? t("wa_premium_access_limited", {}, "Доступ к premium временно ограничен")
|
||||||
|
: t("wa_premium_reset_monthly", {}, "Отдельный лимит на месяц");
|
||||||
|
}
|
||||||
function premiumServerLabels(sub) {
|
function premiumServerLabels(sub) {
|
||||||
return premiumServerLabelsFn(sub);
|
return premiumServerLabelsFn(sub);
|
||||||
}
|
}
|
||||||
@@ -166,7 +172,7 @@
|
|||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
{#if subscription.active}
|
{#if subscription.active}
|
||||||
<Card class={regularTrafficCardClass(subscription)}>
|
<Card compact class={regularTrafficCardClass(subscription)}>
|
||||||
{#if regularTrafficTopupBarClickable}
|
{#if regularTrafficTopupBarClickable}
|
||||||
<button
|
<button
|
||||||
class="card-click-target"
|
class="card-click-target"
|
||||||
@@ -175,45 +181,58 @@
|
|||||||
aria-label={t("wa_add_traffic")}
|
aria-label={t("wa_add_traffic")}
|
||||||
></button>
|
></button>
|
||||||
{/if}
|
{/if}
|
||||||
<div class="traffic-top">
|
<div class="traffic-summary-row">
|
||||||
<span>{t("wa_home_traffic_used")}</span>
|
<span class="traffic-summary-left">
|
||||||
<strong>{trafficLabel(subscription)}</strong>
|
{t("wa_home_traffic_used")}
|
||||||
|
<span class="traffic-summary-separator" aria-hidden="true">|</span>
|
||||||
|
{regularTrafficMetaLabel(subscription)}
|
||||||
|
</span>
|
||||||
|
<strong class="traffic-summary-right">
|
||||||
|
<span>{trafficLabel(subscription)}</span>
|
||||||
|
<span class="traffic-summary-separator" aria-hidden="true">|</span>
|
||||||
|
<span>{trafficPercent(subscription)}%</span>
|
||||||
|
</strong>
|
||||||
</div>
|
</div>
|
||||||
<LinearProgress value={trafficPercent(subscription)} label={t("wa_home_traffic_used")} />
|
<LinearProgress value={trafficPercent(subscription)} label={t("wa_home_traffic_used")} />
|
||||||
<div class="traffic-meta">
|
|
||||||
<span>{regularTrafficMetaLabel(subscription)}</span>
|
|
||||||
<span class="traffic-percent">{trafficPercent(subscription)}%</span>
|
|
||||||
</div>
|
|
||||||
</Card>
|
</Card>
|
||||||
{#if premiumTrafficAvailable(subscription) && subscription?.premium_unlimited_override}
|
{#if premiumTrafficAvailable(subscription) && subscription?.premium_unlimited_override}
|
||||||
<Card class="premium-traffic-card">
|
<Card compact class="traffic-card-compact premium-traffic-card">
|
||||||
<div class="traffic-top">
|
{#if premiumServerLabels(subscription).length}
|
||||||
<span>{premiumTitle(subscription)}</span>
|
<details class="premium-server-dropdown premium-server-dropdown-inline">
|
||||||
<strong>∞</strong>
|
<summary class="traffic-summary-row premium-server-summary">
|
||||||
</div>
|
<span class="traffic-summary-left premium-summary-trigger">
|
||||||
<div class="traffic-meta premium-traffic-meta">
|
<span class="premium-summary-copy">
|
||||||
{#if premiumServerLabels(subscription).length}
|
{premiumTitle(subscription)}
|
||||||
<details class="premium-server-dropdown">
|
<span class="traffic-summary-separator" aria-hidden="true">|</span>
|
||||||
<summary>
|
{t("wa_premium_unlimited", {}, "Безлимит на premium-сервера")}
|
||||||
<span>{t("wa_premium_unlimited", {}, "Безлимит на premium-сервера")}</span>
|
</span>
|
||||||
<ChevronsUpDown size={13} />
|
<CircleQuestionMark class="premium-server-help-icon" size={15} />
|
||||||
</summary>
|
</span>
|
||||||
<div class="premium-server-list premium-server-list-dropdown">
|
<strong class="traffic-summary-right">∞</strong>
|
||||||
<div>
|
</summary>
|
||||||
{#each premiumServerLabels(subscription).slice(0, 8) as label}
|
<div class="premium-server-list premium-server-list-dropdown">
|
||||||
<span>{label}</span>
|
<div>
|
||||||
{/each}
|
{#each premiumServerLabels(subscription).slice(0, 8) as label}
|
||||||
</div>
|
<span>{label}</span>
|
||||||
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
</details>
|
</div>
|
||||||
{:else}
|
</details>
|
||||||
<span>{t("wa_premium_unlimited", {}, "Безлимит на premium-сервера")}</span>
|
{:else}
|
||||||
{/if}
|
<div class="traffic-summary-row">
|
||||||
</div>
|
<span class="traffic-summary-left">
|
||||||
|
{premiumTitle(subscription)}
|
||||||
|
<span class="traffic-summary-separator" aria-hidden="true">|</span>
|
||||||
|
{t("wa_premium_unlimited", {}, "Безлимит на premium-сервера")}
|
||||||
|
</span>
|
||||||
|
<strong class="traffic-summary-right">∞</strong>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
</Card>
|
</Card>
|
||||||
{:else if premiumTrafficAvailable(subscription) && Number(subscription?.premium_limit_bytes || 0) > 0}
|
{:else if premiumTrafficAvailable(subscription) && Number(subscription?.premium_limit_bytes || 0) > 0}
|
||||||
<Card
|
<Card
|
||||||
class={`${premiumTrafficTopupBarClickable ? "traffic-card-clickable " : ""}premium-traffic-card${subscription?.premium_is_limited ? " premium-traffic-card-limited" : ""}`}
|
compact
|
||||||
|
class={`traffic-card-compact ${premiumTrafficTopupBarClickable ? "traffic-card-clickable " : ""}premium-traffic-card${subscription?.premium_is_limited ? " premium-traffic-card-limited" : ""}`}
|
||||||
>
|
>
|
||||||
{#if premiumTrafficTopupBarClickable}
|
{#if premiumTrafficTopupBarClickable}
|
||||||
<button
|
<button
|
||||||
@@ -223,43 +242,50 @@
|
|||||||
aria-label={t("wa_add_traffic_premium", { target: premiumTitle(subscription) })}
|
aria-label={t("wa_add_traffic_premium", { target: premiumTitle(subscription) })}
|
||||||
></button>
|
></button>
|
||||||
{/if}
|
{/if}
|
||||||
<div class="traffic-top">
|
{#if premiumServerLabels(subscription).length}
|
||||||
<span>{premiumTitle(subscription)}</span>
|
<details class="premium-server-dropdown premium-server-dropdown-inline">
|
||||||
<strong>{premiumTrafficLabel(subscription)}</strong>
|
<summary class="traffic-summary-row premium-server-summary">
|
||||||
</div>
|
<span class="traffic-summary-left premium-summary-trigger">
|
||||||
|
<span class="premium-summary-copy">
|
||||||
|
{premiumTitle(subscription)}
|
||||||
|
<span class="traffic-summary-separator" aria-hidden="true">|</span>
|
||||||
|
{premiumTrafficMetaLabel(subscription)}
|
||||||
|
</span>
|
||||||
|
<CircleQuestionMark class="premium-server-help-icon" size={15} />
|
||||||
|
</span>
|
||||||
|
<strong class="traffic-summary-right">
|
||||||
|
<span>{premiumTrafficLabel(subscription)}</span>
|
||||||
|
<span class="traffic-summary-separator" aria-hidden="true">|</span>
|
||||||
|
<span>{premiumTrafficPercent(subscription)}%</span>
|
||||||
|
</strong>
|
||||||
|
</summary>
|
||||||
|
<div class="premium-server-list premium-server-list-dropdown">
|
||||||
|
<div>
|
||||||
|
{#each premiumServerLabels(subscription).slice(0, 8) as label}
|
||||||
|
<span>{label}</span>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
{:else}
|
||||||
|
<div class="traffic-summary-row">
|
||||||
|
<span class="traffic-summary-left">
|
||||||
|
{premiumTitle(subscription)}
|
||||||
|
<span class="traffic-summary-separator" aria-hidden="true">|</span>
|
||||||
|
{premiumTrafficMetaLabel(subscription)}
|
||||||
|
</span>
|
||||||
|
<strong class="traffic-summary-right">
|
||||||
|
<span>{premiumTrafficLabel(subscription)}</span>
|
||||||
|
<span class="traffic-summary-separator" aria-hidden="true">|</span>
|
||||||
|
<span>{premiumTrafficPercent(subscription)}%</span>
|
||||||
|
</strong>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
<LinearProgress
|
<LinearProgress
|
||||||
class="premium-progress"
|
class="premium-progress"
|
||||||
value={premiumTrafficPercent(subscription)}
|
value={premiumTrafficPercent(subscription)}
|
||||||
label={premiumTitle(subscription)}
|
label={premiumTitle(subscription)}
|
||||||
/>
|
/>
|
||||||
<div class="traffic-meta premium-traffic-meta">
|
|
||||||
{#if premiumServerLabels(subscription).length}
|
|
||||||
<details class="premium-server-dropdown">
|
|
||||||
<summary>
|
|
||||||
<span
|
|
||||||
>{subscription?.premium_is_limited
|
|
||||||
? t("wa_premium_access_limited", {}, "Доступ к premium временно ограничен")
|
|
||||||
: t("wa_premium_reset_monthly", {}, "Отдельный лимит на месяц")}</span
|
|
||||||
>
|
|
||||||
<ChevronsUpDown size={13} />
|
|
||||||
</summary>
|
|
||||||
<div class="premium-server-list premium-server-list-dropdown">
|
|
||||||
<div>
|
|
||||||
{#each premiumServerLabels(subscription).slice(0, 8) as label}
|
|
||||||
<span>{label}</span>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</details>
|
|
||||||
{:else}
|
|
||||||
<span
|
|
||||||
>{subscription?.premium_is_limited
|
|
||||||
? t("wa_premium_access_limited", {}, "Доступ к premium временно ограничен")
|
|
||||||
: t("wa_premium_reset_monthly", {}, "Отдельный лимит на месяц")}</span
|
|
||||||
>
|
|
||||||
{/if}
|
|
||||||
<span class="traffic-percent">{premiumTrafficPercent(subscription)}%</span>
|
|
||||||
</div>
|
|
||||||
</Card>
|
</Card>
|
||||||
{/if}
|
{/if}
|
||||||
{:else if trialOfferAvailable}
|
{:else if trialOfferAvailable}
|
||||||
|
|||||||
Reference in New Issue
Block a user