@pegasusheavy/ngx-tailwindcss 0.3.6 → 0.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, makeEnvironmentProviders, inject, PLATFORM_ID, DestroyRef, signal, Injectable, APP_INITIALIZER, computed, LOCALE_ID, effect, ElementRef, Renderer2, booleanAttribute, HostListener, Input, Directive, numberAttribute, NgZone, EventEmitter, Output, ChangeDetectionStrategy, Component, HostBinding, forwardRef, ViewChild, input, output, ContentChildren, ContentChild, viewChild,
|
|
2
|
+
import { InjectionToken, makeEnvironmentProviders, inject, PLATFORM_ID, DestroyRef, signal, Injectable, APP_INITIALIZER, computed, LOCALE_ID, effect, ElementRef, Renderer2, booleanAttribute, HostListener, Input, Directive, numberAttribute, NgZone, EventEmitter, Output, ChangeDetectionStrategy, Component, HostBinding, forwardRef, ViewChild, input, output, ContentChildren, ContentChild, viewChild, contentChildren } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/common';
|
|
4
4
|
import { DOCUMENT, isPlatformBrowser, CommonModule, NgStyle } from '@angular/common';
|
|
5
5
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
@@ -3848,8 +3848,8 @@ const BUTTON_VARIANTS = {
|
|
|
3848
3848
|
warning: 'bg-amber-500 hover:bg-amber-600 active:bg-amber-700 text-white shadow-sm hover:shadow focus-visible:ring-amber-500',
|
|
3849
3849
|
danger: 'bg-rose-600 hover:bg-rose-700 active:bg-rose-800 text-white shadow-sm hover:shadow focus-visible:ring-rose-500',
|
|
3850
3850
|
info: 'bg-cyan-600 hover:bg-cyan-700 active:bg-cyan-800 text-white shadow-sm hover:shadow focus-visible:ring-cyan-500',
|
|
3851
|
-
ghost: 'bg-transparent hover:bg-slate-100
|
|
3852
|
-
outline: 'bg-white
|
|
3851
|
+
ghost: 'bg-transparent hover:bg-slate-100 active:bg-slate-200 text-slate-700 focus-visible:ring-slate-500',
|
|
3852
|
+
outline: 'bg-white border-2 border-slate-500 hover:border-slate-600 hover:bg-slate-100 active:bg-slate-200 text-slate-800 shadow-sm focus-visible:ring-slate-500',
|
|
3853
3853
|
link: 'bg-transparent text-blue-600 hover:text-blue-700 hover:underline active:text-blue-800 focus-visible:ring-blue-500 p-0 shadow-none',
|
|
3854
3854
|
};
|
|
3855
3855
|
const BUTTON_SIZES = {
|
|
@@ -4307,7 +4307,7 @@ class TwInputComponent {
|
|
|
4307
4307
|
useExisting: forwardRef(() => TwInputComponent),
|
|
4308
4308
|
multi: true,
|
|
4309
4309
|
},
|
|
4310
|
-
], viewQueries: [{ propertyName: "inputElement", first: true, predicate: ["inputElement"], descendants: true }], ngImport: i0, template: "@if (label) {\n <label [for]=\"inputId\" class=\"block text-sm font-medium text-slate-700 mb-1.5\">\n {{ label }}\n @if (required) {\n <span class=\"text-rose-500 ml-0.5\">*</span>\n }\n </label>\n}\n\n<div [class]=\"wrapperClasses()\">\n <!-- Prefix -->\n <ng-content select=\"[twInputPrefix]\"></ng-content>\n\n <!-- Input element -->\n <input\n #inputElement\n [id]=\"inputId\"\n [type]=\"type\"\n [class]=\"computedClasses()\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [readonly]=\"readonly\"\n [required]=\"required\"\n [attr.aria-invalid]=\"hasError\"\n [attr.aria-describedby]=\"describedBy\"\n [attr.autocomplete]=\"autocomplete\"\n [attr.inputmode]=\"inputmode\"\n [attr.pattern]=\"pattern\"\n [attr.min]=\"min\"\n [attr.max]=\"max\"\n [attr.minlength]=\"minlength\"\n [attr.maxlength]=\"maxlength\"\n [attr.step]=\"step\"\n [value]=\"value\"\n (input)=\"onInput($event)\"\n (blur)=\"onBlur()\"\n (focus)=\"onFocus.emit($event)\"\n />\n\n <!-- Suffix -->\n <ng-content select=\"[twInputSuffix]\"></ng-content>\n\n <!-- Clear button -->\n @if (clearable && value && !disabled && !readonly) {\n <button\n type=\"button\"\n class=\"flex items-center justify-center w-5 h-5 text-slate-400 hover:text-slate-600 transition-colors\"\n (click)=\"clear()\"\n aria-label=\"Clear input\"\n >\n <svg class=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n }\n</div>\n\n@if (hint && !error) {\n <span class=\"block text-xs text-slate-500 mt-1.5\">{{ hint }}</span>\n}\n\n@if (error) {\n <span class=\"block text-xs text-rose-600 mt-1.5\" role=\"alert\">{{ error }}</span>\n}\n\n<ng-content select=\"tw-hint, [twHint], tw-error, [twError]\"></ng-content>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4310
|
+
], viewQueries: [{ propertyName: "inputElement", first: true, predicate: ["inputElement"], descendants: true }], ngImport: i0, template: "@if (label) {\n <label [for]=\"inputId\" class=\"block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1.5\">\n {{ label }}\n @if (required) {\n <span class=\"text-rose-500 ml-0.5\">*</span>\n }\n </label>\n}\n\n<div [class]=\"wrapperClasses()\">\n <!-- Prefix -->\n <ng-content select=\"[twInputPrefix]\"></ng-content>\n\n <!-- Input element -->\n <input\n #inputElement\n [id]=\"inputId\"\n [type]=\"type\"\n [class]=\"computedClasses()\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [readonly]=\"readonly\"\n [required]=\"required\"\n [attr.aria-invalid]=\"hasError\"\n [attr.aria-describedby]=\"describedBy\"\n [attr.autocomplete]=\"autocomplete\"\n [attr.inputmode]=\"inputmode\"\n [attr.pattern]=\"pattern\"\n [attr.min]=\"min\"\n [attr.max]=\"max\"\n [attr.minlength]=\"minlength\"\n [attr.maxlength]=\"maxlength\"\n [attr.step]=\"step\"\n [value]=\"value\"\n (input)=\"onInput($event)\"\n (blur)=\"onBlur()\"\n (focus)=\"onFocus.emit($event)\"\n />\n\n <!-- Suffix -->\n <ng-content select=\"[twInputSuffix]\"></ng-content>\n\n <!-- Clear button -->\n @if (clearable && value && !disabled && !readonly) {\n <button\n type=\"button\"\n class=\"flex items-center justify-center w-5 h-5 text-slate-400 hover:text-slate-600 dark:text-slate-500 dark:hover:text-slate-300 transition-colors\"\n (click)=\"clear()\"\n aria-label=\"Clear input\"\n >\n <svg class=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n }\n</div>\n\n@if (hint && !error) {\n <span class=\"block text-xs text-slate-500 dark:text-slate-400 mt-1.5\">{{ hint }}</span>\n}\n\n@if (error) {\n <span class=\"block text-xs text-rose-600 mt-1.5\" role=\"alert\">{{ error }}</span>\n}\n\n<ng-content select=\"tw-hint, [twHint], tw-error, [twError]\"></ng-content>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4311
4311
|
}
|
|
4312
4312
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TwInputComponent, decorators: [{
|
|
4313
4313
|
type: Component,
|
|
@@ -4319,7 +4319,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
4319
4319
|
},
|
|
4320
4320
|
], host: {
|
|
4321
4321
|
class: 'block',
|
|
4322
|
-
}, template: "@if (label) {\n <label [for]=\"inputId\" class=\"block text-sm font-medium text-slate-700 mb-1.5\">\n {{ label }}\n @if (required) {\n <span class=\"text-rose-500 ml-0.5\">*</span>\n }\n </label>\n}\n\n<div [class]=\"wrapperClasses()\">\n <!-- Prefix -->\n <ng-content select=\"[twInputPrefix]\"></ng-content>\n\n <!-- Input element -->\n <input\n #inputElement\n [id]=\"inputId\"\n [type]=\"type\"\n [class]=\"computedClasses()\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [readonly]=\"readonly\"\n [required]=\"required\"\n [attr.aria-invalid]=\"hasError\"\n [attr.aria-describedby]=\"describedBy\"\n [attr.autocomplete]=\"autocomplete\"\n [attr.inputmode]=\"inputmode\"\n [attr.pattern]=\"pattern\"\n [attr.min]=\"min\"\n [attr.max]=\"max\"\n [attr.minlength]=\"minlength\"\n [attr.maxlength]=\"maxlength\"\n [attr.step]=\"step\"\n [value]=\"value\"\n (input)=\"onInput($event)\"\n (blur)=\"onBlur()\"\n (focus)=\"onFocus.emit($event)\"\n />\n\n <!-- Suffix -->\n <ng-content select=\"[twInputSuffix]\"></ng-content>\n\n <!-- Clear button -->\n @if (clearable && value && !disabled && !readonly) {\n <button\n type=\"button\"\n class=\"flex items-center justify-center w-5 h-5 text-slate-400 hover:text-slate-600 transition-colors\"\n (click)=\"clear()\"\n aria-label=\"Clear input\"\n >\n <svg class=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n }\n</div>\n\n@if (hint && !error) {\n <span class=\"block text-xs text-slate-500 mt-1.5\">{{ hint }}</span>\n}\n\n@if (error) {\n <span class=\"block text-xs text-rose-600 mt-1.5\" role=\"alert\">{{ error }}</span>\n}\n\n<ng-content select=\"tw-hint, [twHint], tw-error, [twError]\"></ng-content>\n" }]
|
|
4322
|
+
}, template: "@if (label) {\n <label [for]=\"inputId\" class=\"block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1.5\">\n {{ label }}\n @if (required) {\n <span class=\"text-rose-500 ml-0.5\">*</span>\n }\n </label>\n}\n\n<div [class]=\"wrapperClasses()\">\n <!-- Prefix -->\n <ng-content select=\"[twInputPrefix]\"></ng-content>\n\n <!-- Input element -->\n <input\n #inputElement\n [id]=\"inputId\"\n [type]=\"type\"\n [class]=\"computedClasses()\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [readonly]=\"readonly\"\n [required]=\"required\"\n [attr.aria-invalid]=\"hasError\"\n [attr.aria-describedby]=\"describedBy\"\n [attr.autocomplete]=\"autocomplete\"\n [attr.inputmode]=\"inputmode\"\n [attr.pattern]=\"pattern\"\n [attr.min]=\"min\"\n [attr.max]=\"max\"\n [attr.minlength]=\"minlength\"\n [attr.maxlength]=\"maxlength\"\n [attr.step]=\"step\"\n [value]=\"value\"\n (input)=\"onInput($event)\"\n (blur)=\"onBlur()\"\n (focus)=\"onFocus.emit($event)\"\n />\n\n <!-- Suffix -->\n <ng-content select=\"[twInputSuffix]\"></ng-content>\n\n <!-- Clear button -->\n @if (clearable && value && !disabled && !readonly) {\n <button\n type=\"button\"\n class=\"flex items-center justify-center w-5 h-5 text-slate-400 hover:text-slate-600 dark:text-slate-500 dark:hover:text-slate-300 transition-colors\"\n (click)=\"clear()\"\n aria-label=\"Clear input\"\n >\n <svg class=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n }\n</div>\n\n@if (hint && !error) {\n <span class=\"block text-xs text-slate-500 dark:text-slate-400 mt-1.5\">{{ hint }}</span>\n}\n\n@if (error) {\n <span class=\"block text-xs text-rose-600 mt-1.5\" role=\"alert\">{{ error }}</span>\n}\n\n<ng-content select=\"tw-hint, [twHint], tw-error, [twError]\"></ng-content>\n" }]
|
|
4323
4323
|
}], propDecorators: { inputElement: [{
|
|
4324
4324
|
type: ViewChild,
|
|
4325
4325
|
args: ['inputElement']
|
|
@@ -4452,7 +4452,7 @@ class TwTextareaComponent {
|
|
|
4452
4452
|
useExisting: forwardRef(() => TwTextareaComponent),
|
|
4453
4453
|
multi: true,
|
|
4454
4454
|
},
|
|
4455
|
-
], viewQueries: [{ propertyName: "textareaElement", first: true, predicate: ["textareaElement"], descendants: true }], ngImport: i0, template: "@if (label) {\n <label [for]=\"inputId\" class=\"block text-sm font-medium text-slate-700 mb-1.5\">\n {{ label }}\n @if (required) {\n <span class=\"text-rose-500 ml-0.5\">*</span>\n }\n </label>\n}\n\n<textarea\n #textareaElement\n [id]=\"inputId\"\n [class]=\"computedClasses()\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [readonly]=\"readonly\"\n [required]=\"required\"\n [rows]=\"rows\"\n [attr.aria-invalid]=\"hasError\"\n [attr.minlength]=\"minlength\"\n [attr.maxlength]=\"maxlength\"\n [value]=\"value\"\n (input)=\"onInput($event)\"\n (blur)=\"onBlur()\"\n></textarea>\n\n@if (hint && !error) {\n <span class=\"block text-xs text-slate-500 mt-1.5\">{{ hint }}</span>\n}\n\n@if (error) {\n <span class=\"block text-xs text-rose-600 mt-1.5\" role=\"alert\">{{ error }}</span>\n}\n\n@if (maxlength && showCount) {\n <span class=\"block text-xs text-slate-400 mt-1 text-right\">\n {{ value.length }} / {{ maxlength }}\n </span>\n}\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4455
|
+
], viewQueries: [{ propertyName: "textareaElement", first: true, predicate: ["textareaElement"], descendants: true }], ngImport: i0, template: "@if (label) {\n <label [for]=\"inputId\" class=\"block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1.5\">\n {{ label }}\n @if (required) {\n <span class=\"text-rose-500 ml-0.5\">*</span>\n }\n </label>\n}\n\n<textarea\n #textareaElement\n [id]=\"inputId\"\n [class]=\"computedClasses()\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [readonly]=\"readonly\"\n [required]=\"required\"\n [rows]=\"rows\"\n [attr.aria-invalid]=\"hasError\"\n [attr.minlength]=\"minlength\"\n [attr.maxlength]=\"maxlength\"\n [value]=\"value\"\n (input)=\"onInput($event)\"\n (blur)=\"onBlur()\"\n></textarea>\n\n@if (hint && !error) {\n <span class=\"block text-xs text-slate-500 dark:text-slate-400 mt-1.5\">{{ hint }}</span>\n}\n\n@if (error) {\n <span class=\"block text-xs text-rose-600 mt-1.5\" role=\"alert\">{{ error }}</span>\n}\n\n@if (maxlength && showCount) {\n <span class=\"block text-xs text-slate-400 mt-1 text-right\">\n {{ value.length }} / {{ maxlength }}\n </span>\n}\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4456
4456
|
}
|
|
4457
4457
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TwTextareaComponent, decorators: [{
|
|
4458
4458
|
type: Component,
|
|
@@ -4464,7 +4464,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
4464
4464
|
},
|
|
4465
4465
|
], host: {
|
|
4466
4466
|
class: 'block',
|
|
4467
|
-
}, template: "@if (label) {\n <label [for]=\"inputId\" class=\"block text-sm font-medium text-slate-700 mb-1.5\">\n {{ label }}\n @if (required) {\n <span class=\"text-rose-500 ml-0.5\">*</span>\n }\n </label>\n}\n\n<textarea\n #textareaElement\n [id]=\"inputId\"\n [class]=\"computedClasses()\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [readonly]=\"readonly\"\n [required]=\"required\"\n [rows]=\"rows\"\n [attr.aria-invalid]=\"hasError\"\n [attr.minlength]=\"minlength\"\n [attr.maxlength]=\"maxlength\"\n [value]=\"value\"\n (input)=\"onInput($event)\"\n (blur)=\"onBlur()\"\n></textarea>\n\n@if (hint && !error) {\n <span class=\"block text-xs text-slate-500 mt-1.5\">{{ hint }}</span>\n}\n\n@if (error) {\n <span class=\"block text-xs text-rose-600 mt-1.5\" role=\"alert\">{{ error }}</span>\n}\n\n@if (maxlength && showCount) {\n <span class=\"block text-xs text-slate-400 mt-1 text-right\">\n {{ value.length }} / {{ maxlength }}\n </span>\n}\n" }]
|
|
4467
|
+
}, template: "@if (label) {\n <label [for]=\"inputId\" class=\"block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1.5\">\n {{ label }}\n @if (required) {\n <span class=\"text-rose-500 ml-0.5\">*</span>\n }\n </label>\n}\n\n<textarea\n #textareaElement\n [id]=\"inputId\"\n [class]=\"computedClasses()\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [readonly]=\"readonly\"\n [required]=\"required\"\n [rows]=\"rows\"\n [attr.aria-invalid]=\"hasError\"\n [attr.minlength]=\"minlength\"\n [attr.maxlength]=\"maxlength\"\n [value]=\"value\"\n (input)=\"onInput($event)\"\n (blur)=\"onBlur()\"\n></textarea>\n\n@if (hint && !error) {\n <span class=\"block text-xs text-slate-500 dark:text-slate-400 mt-1.5\">{{ hint }}</span>\n}\n\n@if (error) {\n <span class=\"block text-xs text-rose-600 mt-1.5\" role=\"alert\">{{ error }}</span>\n}\n\n@if (maxlength && showCount) {\n <span class=\"block text-xs text-slate-400 mt-1 text-right\">\n {{ value.length }} / {{ maxlength }}\n </span>\n}\n" }]
|
|
4468
4468
|
}], propDecorators: { textareaElement: [{
|
|
4469
4469
|
type: ViewChild,
|
|
4470
4470
|
args: ['textareaElement']
|
|
@@ -9799,19 +9799,16 @@ class TwPaginationComponent {
|
|
|
9799
9799
|
const rightSiblingIndex = Math.min(current + siblings, total);
|
|
9800
9800
|
const showLeftEllipsis = leftSiblingIndex > 2;
|
|
9801
9801
|
const showRightEllipsis = rightSiblingIndex < total - 1;
|
|
9802
|
-
// Use unique ellipsis identifiers to avoid duplicate keys in @for tracking
|
|
9803
|
-
const LEFT_ELLIPSIS = '...left';
|
|
9804
|
-
const RIGHT_ELLIPSIS = '...right';
|
|
9805
9802
|
if (!showLeftEllipsis && showRightEllipsis) {
|
|
9806
9803
|
const leftRange = range(1, 3 + siblings * 2);
|
|
9807
|
-
return [...leftRange.map(String),
|
|
9804
|
+
return [...leftRange.map(String), '...', String(total)];
|
|
9808
9805
|
}
|
|
9809
9806
|
if (showLeftEllipsis && !showRightEllipsis) {
|
|
9810
9807
|
const rightRange = range(total - (3 + siblings * 2) + 1, total);
|
|
9811
|
-
return ['1',
|
|
9808
|
+
return ['1', '...', ...rightRange.map(String)];
|
|
9812
9809
|
}
|
|
9813
9810
|
const middleRange = range(leftSiblingIndex, rightSiblingIndex);
|
|
9814
|
-
return ['1',
|
|
9811
|
+
return ['1', '...', ...middleRange.map(String), '...', String(total)];
|
|
9815
9812
|
}, ...(ngDevMode ? [{ debugName: "visiblePages" }] : []));
|
|
9816
9813
|
goToPage(page) {
|
|
9817
9814
|
if (page >= 1 && page <= this.totalPagesValue() && page !== this._currentPage()) {
|
|
@@ -9886,11 +9883,11 @@ class TwPaginationComponent {
|
|
|
9886
9883
|
return baseClasses.join(' ');
|
|
9887
9884
|
}
|
|
9888
9885
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TwPaginationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
9889
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: TwPaginationComponent, isStandalone: true, selector: "tw-pagination", inputs: { currentPage: "currentPage", totalPages: "totalPages", totalItems: "totalItems", itemsPerPage: "itemsPerPage", siblingCount: "siblingCount", size: "size", variant: "variant", showFirstLast: "showFirstLast" }, outputs: { pageChange: "pageChange" }, ngImport: i0, template: "@switch (variantValue()) {\n @case ('simple') {\n <div class=\"flex items-center justify-between\">\n <button\n type=\"button\"\n [disabled]=\"currentPageValue() <= 1\"\n [class]=\"simpleButtonClasses(currentPageValue() <= 1)\"\n (click)=\"goToPage(currentPageValue() - 1)\"\n >\n <svg\n class=\"w-5 h-5 mr-1\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15 19l-7-7 7-7\" />\n </svg>\n Previous\n </button>\n <span class=\"text-sm text-slate-600\">\n Page {{ currentPageValue() }} of {{ totalPagesValue() }}\n </span>\n <button\n type=\"button\"\n [disabled]=\"currentPageValue() >= totalPagesValue()\"\n [class]=\"simpleButtonClasses(currentPageValue() >= totalPagesValue())\"\n (click)=\"goToPage(currentPageValue() + 1)\"\n >\n Next\n <svg\n class=\"w-5 h-5 ml-1\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5l7 7-7 7\" />\n </svg>\n </button>\n </div>\n }\n @default {\n <nav class=\"flex items-center gap-1\" aria-label=\"Pagination\">\n <!-- Previous -->\n <button\n type=\"button\"\n [disabled]=\"currentPageValue() <= 1\"\n [class]=\"navButtonClasses(currentPageValue() <= 1)\"\n (click)=\"goToPage(currentPageValue() - 1)\"\n aria-label=\"Previous page\"\n >\n <svg class=\"w-5 h-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15 19l-7-7 7-7\" />\n </svg>\n </button>\n\n <!-- Page numbers -->\n @for (page of visiblePages(); track page) {\n @if (page
|
|
9886
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: TwPaginationComponent, isStandalone: true, selector: "tw-pagination", inputs: { currentPage: "currentPage", totalPages: "totalPages", totalItems: "totalItems", itemsPerPage: "itemsPerPage", siblingCount: "siblingCount", size: "size", variant: "variant", showFirstLast: "showFirstLast" }, outputs: { pageChange: "pageChange" }, ngImport: i0, template: "@switch (variantValue()) {\n @case ('simple') {\n <div class=\"flex items-center justify-between\">\n <button\n type=\"button\"\n [disabled]=\"currentPageValue() <= 1\"\n [class]=\"simpleButtonClasses(currentPageValue() <= 1)\"\n (click)=\"goToPage(currentPageValue() - 1)\"\n >\n <svg\n class=\"w-5 h-5 mr-1\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15 19l-7-7 7-7\" />\n </svg>\n Previous\n </button>\n <span class=\"text-sm text-slate-600\">\n Page {{ currentPageValue() }} of {{ totalPagesValue() }}\n </span>\n <button\n type=\"button\"\n [disabled]=\"currentPageValue() >= totalPagesValue()\"\n [class]=\"simpleButtonClasses(currentPageValue() >= totalPagesValue())\"\n (click)=\"goToPage(currentPageValue() + 1)\"\n >\n Next\n <svg\n class=\"w-5 h-5 ml-1\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5l7 7-7 7\" />\n </svg>\n </button>\n </div>\n }\n @default {\n <nav class=\"flex items-center gap-1\" aria-label=\"Pagination\">\n <!-- Previous -->\n <button\n type=\"button\"\n [disabled]=\"currentPageValue() <= 1\"\n [class]=\"navButtonClasses(currentPageValue() <= 1)\"\n (click)=\"goToPage(currentPageValue() - 1)\"\n aria-label=\"Previous page\"\n >\n <svg class=\"w-5 h-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15 19l-7-7 7-7\" />\n </svg>\n </button>\n\n <!-- Page numbers -->\n @for (page of visiblePages(); track page) {\n @if (page === '...') {\n <span [class]=\"ellipsisClasses()\">...</span>\n } @else {\n <button\n type=\"button\"\n [class]=\"pageButtonClasses(+page === currentPageValue())\"\n [attr.aria-current]=\"+page === currentPageValue() ? 'page' : null\"\n (click)=\"goToPage(+page)\"\n >\n {{ page }}\n </button>\n }\n }\n\n <!-- Next -->\n <button\n type=\"button\"\n [disabled]=\"currentPageValue() >= totalPagesValue()\"\n [class]=\"navButtonClasses(currentPageValue() >= totalPagesValue())\"\n (click)=\"goToPage(currentPageValue() + 1)\"\n aria-label=\"Next page\"\n >\n <svg class=\"w-5 h-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5l7 7-7 7\" />\n </svg>\n </button>\n </nav>\n }\n}\n", dependencies: [{ kind: "ngmodule", type: CommonModule }] });
|
|
9890
9887
|
}
|
|
9891
9888
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TwPaginationComponent, decorators: [{
|
|
9892
9889
|
type: Component,
|
|
9893
|
-
args: [{ selector: 'tw-pagination', standalone: true, imports: [CommonModule], template: "@switch (variantValue()) {\n @case ('simple') {\n <div class=\"flex items-center justify-between\">\n <button\n type=\"button\"\n [disabled]=\"currentPageValue() <= 1\"\n [class]=\"simpleButtonClasses(currentPageValue() <= 1)\"\n (click)=\"goToPage(currentPageValue() - 1)\"\n >\n <svg\n class=\"w-5 h-5 mr-1\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15 19l-7-7 7-7\" />\n </svg>\n Previous\n </button>\n <span class=\"text-sm text-slate-600\">\n Page {{ currentPageValue() }} of {{ totalPagesValue() }}\n </span>\n <button\n type=\"button\"\n [disabled]=\"currentPageValue() >= totalPagesValue()\"\n [class]=\"simpleButtonClasses(currentPageValue() >= totalPagesValue())\"\n (click)=\"goToPage(currentPageValue() + 1)\"\n >\n Next\n <svg\n class=\"w-5 h-5 ml-1\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5l7 7-7 7\" />\n </svg>\n </button>\n </div>\n }\n @default {\n <nav class=\"flex items-center gap-1\" aria-label=\"Pagination\">\n <!-- Previous -->\n <button\n type=\"button\"\n [disabled]=\"currentPageValue() <= 1\"\n [class]=\"navButtonClasses(currentPageValue() <= 1)\"\n (click)=\"goToPage(currentPageValue() - 1)\"\n aria-label=\"Previous page\"\n >\n <svg class=\"w-5 h-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15 19l-7-7 7-7\" />\n </svg>\n </button>\n\n <!-- Page numbers -->\n @for (page of visiblePages(); track page) {\n @if (page
|
|
9890
|
+
args: [{ selector: 'tw-pagination', standalone: true, imports: [CommonModule], template: "@switch (variantValue()) {\n @case ('simple') {\n <div class=\"flex items-center justify-between\">\n <button\n type=\"button\"\n [disabled]=\"currentPageValue() <= 1\"\n [class]=\"simpleButtonClasses(currentPageValue() <= 1)\"\n (click)=\"goToPage(currentPageValue() - 1)\"\n >\n <svg\n class=\"w-5 h-5 mr-1\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15 19l-7-7 7-7\" />\n </svg>\n Previous\n </button>\n <span class=\"text-sm text-slate-600\">\n Page {{ currentPageValue() }} of {{ totalPagesValue() }}\n </span>\n <button\n type=\"button\"\n [disabled]=\"currentPageValue() >= totalPagesValue()\"\n [class]=\"simpleButtonClasses(currentPageValue() >= totalPagesValue())\"\n (click)=\"goToPage(currentPageValue() + 1)\"\n >\n Next\n <svg\n class=\"w-5 h-5 ml-1\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5l7 7-7 7\" />\n </svg>\n </button>\n </div>\n }\n @default {\n <nav class=\"flex items-center gap-1\" aria-label=\"Pagination\">\n <!-- Previous -->\n <button\n type=\"button\"\n [disabled]=\"currentPageValue() <= 1\"\n [class]=\"navButtonClasses(currentPageValue() <= 1)\"\n (click)=\"goToPage(currentPageValue() - 1)\"\n aria-label=\"Previous page\"\n >\n <svg class=\"w-5 h-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15 19l-7-7 7-7\" />\n </svg>\n </button>\n\n <!-- Page numbers -->\n @for (page of visiblePages(); track page) {\n @if (page === '...') {\n <span [class]=\"ellipsisClasses()\">...</span>\n } @else {\n <button\n type=\"button\"\n [class]=\"pageButtonClasses(+page === currentPageValue())\"\n [attr.aria-current]=\"+page === currentPageValue() ? 'page' : null\"\n (click)=\"goToPage(+page)\"\n >\n {{ page }}\n </button>\n }\n }\n\n <!-- Next -->\n <button\n type=\"button\"\n [disabled]=\"currentPageValue() >= totalPagesValue()\"\n [class]=\"navButtonClasses(currentPageValue() >= totalPagesValue())\"\n (click)=\"goToPage(currentPageValue() + 1)\"\n aria-label=\"Next page\"\n >\n <svg class=\"w-5 h-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5l7 7-7 7\" />\n </svg>\n </button>\n </nav>\n }\n}\n" }]
|
|
9894
9891
|
}], propDecorators: { currentPage: [{
|
|
9895
9892
|
type: Input
|
|
9896
9893
|
}], totalPages: [{
|
|
@@ -13210,8 +13207,6 @@ class TwVolumeDialComponent {
|
|
|
13210
13207
|
a11y = inject(MusicAccessibilityService);
|
|
13211
13208
|
dialSvg = viewChild('dialSvg', ...(ngDevMode ? [{ debugName: "dialSvg" }] : []));
|
|
13212
13209
|
// Inputs
|
|
13213
|
-
/** Initial/bound value - supports two-way binding with [(value)] */
|
|
13214
|
-
value = model(0, ...(ngDevMode ? [{ debugName: "value" }] : []));
|
|
13215
13210
|
min = input(0, ...(ngDevMode ? [{ debugName: "min" }] : []));
|
|
13216
13211
|
max = input(100, ...(ngDevMode ? [{ debugName: "max" }] : []));
|
|
13217
13212
|
step = input(1, ...(ngDevMode ? [{ debugName: "step" }] : []));
|
|
@@ -13238,8 +13233,10 @@ class TwVolumeDialComponent {
|
|
|
13238
13233
|
announceChanges = input(true, ...(ngDevMode ? [{ debugName: "announceChanges" }] : [])); // Announce value changes to screen readers
|
|
13239
13234
|
reducedMotion = input('auto', ...(ngDevMode ? [{ debugName: "reducedMotion" }] : [])); // Respect reduced motion preference
|
|
13240
13235
|
// Outputs
|
|
13241
|
-
|
|
13236
|
+
valueChange = output();
|
|
13242
13237
|
hapticTrigger = output(); // Haptic feedback trigger points
|
|
13238
|
+
// Internal state
|
|
13239
|
+
value = signal(0, ...(ngDevMode ? [{ debugName: "value" }] : []));
|
|
13243
13240
|
isDragging = false;
|
|
13244
13241
|
startAngle = 0;
|
|
13245
13242
|
startValue = 0;
|
|
@@ -13490,6 +13487,7 @@ class TwVolumeDialComponent {
|
|
|
13490
13487
|
if (newValue !== this.value()) {
|
|
13491
13488
|
this.value.set(newValue);
|
|
13492
13489
|
this.onChangeFn(newValue);
|
|
13490
|
+
this.valueChange.emit(newValue);
|
|
13493
13491
|
// Announce to screen readers (debounced)
|
|
13494
13492
|
if (this.announceChanges()) {
|
|
13495
13493
|
this.a11y.announceValueChange(this.label() || 'Volume', this.displayValue(), this.unit());
|
|
@@ -13510,7 +13508,7 @@ class TwVolumeDialComponent {
|
|
|
13510
13508
|
// Disabled state is handled via input
|
|
13511
13509
|
}
|
|
13512
13510
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TwVolumeDialComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
13513
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: TwVolumeDialComponent, isStandalone: true, selector: "tw-volume-dial", inputs: {
|
|
13511
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: TwVolumeDialComponent, isStandalone: true, selector: "tw-volume-dial", inputs: { min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, step: { classPropertyName: "step", publicName: "step", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, showValue: { classPropertyName: "showValue", publicName: "showValue", isSignal: true, isRequired: false, transformFunction: null }, showTicks: { classPropertyName: "showTicks", publicName: "showTicks", isSignal: true, isRequired: false, transformFunction: null }, showLabel: { classPropertyName: "showLabel", publicName: "showLabel", isSignal: true, isRequired: false, transformFunction: null }, showLedRing: { classPropertyName: "showLedRing", publicName: "showLedRing", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, unit: { classPropertyName: "unit", publicName: "unit", isSignal: true, isRequired: false, transformFunction: null }, centerDetent: { classPropertyName: "centerDetent", publicName: "centerDetent", isSignal: true, isRequired: false, transformFunction: null }, detentValue: { classPropertyName: "detentValue", publicName: "detentValue", isSignal: true, isRequired: false, transformFunction: null }, classOverride: { classPropertyName: "classOverride", publicName: "classOverride", isSignal: true, isRequired: false, transformFunction: null }, customSize: { classPropertyName: "customSize", publicName: "customSize", isSignal: true, isRequired: false, transformFunction: null }, customStrokeWidth: { classPropertyName: "customStrokeWidth", publicName: "customStrokeWidth", isSignal: true, isRequired: false, transformFunction: null }, hapticFeedback: { classPropertyName: "hapticFeedback", publicName: "hapticFeedback", isSignal: true, isRequired: false, transformFunction: null }, touchGuard: { classPropertyName: "touchGuard", publicName: "touchGuard", isSignal: true, isRequired: false, transformFunction: null }, minTouchDuration: { classPropertyName: "minTouchDuration", publicName: "minTouchDuration", isSignal: true, isRequired: false, transformFunction: null }, announceChanges: { classPropertyName: "announceChanges", publicName: "announceChanges", isSignal: true, isRequired: false, transformFunction: null }, reducedMotion: { classPropertyName: "reducedMotion", publicName: "reducedMotion", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange", hapticTrigger: "hapticTrigger" }, host: { classAttribute: "inline-block" }, providers: [
|
|
13514
13512
|
{
|
|
13515
13513
|
provide: NG_VALUE_ACCESSOR,
|
|
13516
13514
|
useExisting: forwardRef(() => TwVolumeDialComponent),
|
|
@@ -13529,7 +13527,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
13529
13527
|
], host: {
|
|
13530
13528
|
class: 'inline-block',
|
|
13531
13529
|
}, template: "<div\n [class]=\"containerClasses()\"\n [style.width.px]=\"sizeConfig().size\"\n [style.height.px]=\"sizeConfig().size + (showValue() ? 24 : 0)\"\n>\n <!-- SVG Dial -->\n <svg\n #dialSvg\n [attr.width]=\"sizeConfig().size\"\n [attr.height]=\"sizeConfig().size\"\n [attr.viewBox]=\"'0 0 ' + sizeConfig().size + ' ' + sizeConfig().size\"\n class=\"cursor-pointer select-none\"\n [class.opacity-50]=\"disabled()\"\n [class.cursor-not-allowed]=\"disabled()\"\n (mousedown)=\"onMouseDown($event)\"\n (touchstart)=\"onTouchStart($event)\"\n (keydown)=\"onKeyDown($event)\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n role=\"slider\"\n [attr.aria-valuenow]=\"value()\"\n [attr.aria-valuemin]=\"min()\"\n [attr.aria-valuemax]=\"max()\"\n [attr.aria-label]=\"label() || 'Volume dial'\"\n [attr.aria-disabled]=\"disabled()\"\n >\n <!-- Track (background arc) -->\n <path\n [attr.d]=\"trackPath()\"\n fill=\"none\"\n [attr.stroke-width]=\"sizeConfig().strokeWidth\"\n [class]=\"variantConfig().track\"\n stroke-linecap=\"round\"\n />\n\n <!-- Fill (value arc) -->\n <path\n [attr.d]=\"fillPath()\"\n fill=\"none\"\n [attr.stroke-width]=\"sizeConfig().strokeWidth\"\n [class]=\"variantConfig().fill\"\n stroke-linecap=\"round\"\n />\n\n <!-- Tick marks -->\n @if (showTicks()) {\n @for (tick of tickMarks(); track tick.angle) {\n <line\n [attr.x1]=\"tick.x1\"\n [attr.y1]=\"tick.y1\"\n [attr.x2]=\"tick.x2\"\n [attr.y2]=\"tick.y2\"\n [class]=\"\n tick.isMajor\n ? 'stroke-slate-400 dark:stroke-slate-500'\n : 'stroke-slate-300 dark:stroke-slate-600'\n \"\n [attr.stroke-width]=\"tick.isMajor ? 2 : 1\"\n />\n }\n }\n\n <!-- Knob center -->\n <circle\n [attr.cx]=\"center()\"\n [attr.cy]=\"center()\"\n [attr.r]=\"knobRadius()\"\n [class]=\"variantConfig().knob\"\n stroke-width=\"2\"\n />\n\n <!-- Indicator line -->\n <line\n [attr.x1]=\"center()\"\n [attr.y1]=\"center()\"\n [attr.x2]=\"indicatorEnd().x\"\n [attr.y2]=\"indicatorEnd().y\"\n [class]=\"variantConfig().indicator\"\n [attr.stroke-width]=\"sizeConfig().strokeWidth - 1\"\n stroke-linecap=\"round\"\n />\n\n <!-- LED ring (for led variant) -->\n @if (variant() === 'led' && showLedRing()) {\n @for (led of ledSegments(); track led.index) {\n <circle\n [attr.cx]=\"led.x\"\n [attr.cy]=\"led.y\"\n [attr.r]=\"3\"\n [class]=\"led.active ? 'fill-emerald-400' : 'fill-slate-700'\"\n />\n }\n }\n </svg>\n\n <!-- Value display -->\n @if (showValue()) {\n <div [class]=\"valueClasses()\">{{ displayValue() }}{{ unit() }}</div>\n }\n\n <!-- Label -->\n @if (label() && showLabel()) {\n <div\n class=\"absolute -bottom-6 left-1/2 -translate-x-1/2 text-xs text-slate-500 dark:text-slate-400 whitespace-nowrap\"\n >\n {{ label() }}\n </div>\n }\n</div>\n" }]
|
|
13532
|
-
}], propDecorators: { dialSvg: [{ type: i0.ViewChild, args: ['dialSvg', { isSignal: true }] }],
|
|
13530
|
+
}], propDecorators: { dialSvg: [{ type: i0.ViewChild, args: ['dialSvg', { isSignal: true }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], step: [{ type: i0.Input, args: [{ isSignal: true, alias: "step", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], showValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "showValue", required: false }] }], showTicks: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTicks", required: false }] }], showLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLabel", required: false }] }], showLedRing: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLedRing", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], unit: [{ type: i0.Input, args: [{ isSignal: true, alias: "unit", required: false }] }], centerDetent: [{ type: i0.Input, args: [{ isSignal: true, alias: "centerDetent", required: false }] }], detentValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "detentValue", required: false }] }], classOverride: [{ type: i0.Input, args: [{ isSignal: true, alias: "classOverride", required: false }] }], customSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "customSize", required: false }] }], customStrokeWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "customStrokeWidth", required: false }] }], hapticFeedback: [{ type: i0.Input, args: [{ isSignal: true, alias: "hapticFeedback", required: false }] }], touchGuard: [{ type: i0.Input, args: [{ isSignal: true, alias: "touchGuard", required: false }] }], minTouchDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "minTouchDuration", required: false }] }], announceChanges: [{ type: i0.Input, args: [{ isSignal: true, alias: "announceChanges", required: false }] }], reducedMotion: [{ type: i0.Input, args: [{ isSignal: true, alias: "reducedMotion", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], hapticTrigger: [{ type: i0.Output, args: ["hapticTrigger"] }] } });
|
|
13533
13531
|
|
|
13534
13532
|
// RMS calculation window size (samples)
|
|
13535
13533
|
const RMS_WINDOW_SIZE = 1024;
|
|
@@ -19135,7 +19133,7 @@ class TwChannelStripComponent {
|
|
|
19135
19133
|
useExisting: forwardRef(() => TwChannelStripComponent),
|
|
19136
19134
|
multi: true,
|
|
19137
19135
|
},
|
|
19138
|
-
], ngImport: i0, template: "<div [class]=\"containerClasses()\">\n <!-- Channel Label with Signal Indicator -->\n @if (showLabel()) {\n <div [class]=\"labelClasses()\" class=\"relative flex items-center justify-center gap-1\">\n <!-- Signal Present Indicator -->\n @if (showSignalIndicator()) {\n <div\n class=\"w-2 h-2 rounded-full transition-all duration-150\"\n [class.bg-green-500]=\"signalPresent()\"\n [class.shadow-[0_0_6px_rgba(34,197,94,0.8)]]=\"signalPresent()\"\n [class.bg-slate-600]=\"!signalPresent()\"\n title=\"Signal Present\"\n ></div>\n }\n <span class=\"text-slate-400\">{{ channelNumber() }}</span>\n <span class=\"text-white\">{{ label() }}</span>\n </div>\n }\n\n <!-- Input Gain Control -->\n @if (showInputGain()) {\n <div class=\"flex flex-col items-center gap-1\">\n <tw-volume-dial\n [ngModel]=\"inputGain()\"\n (ngModelChange)=\"onInputGainChange($event)\"\n [min]=\"-20\"\n [max]=\"20\"\n [step]=\"1\"\n [size]=\"size() === 'lg' ? 'sm' : 'xs'\"\n [variant]=\"variant() === 'vintage' ? 'vintage' : 'minimal'\"\n [disabled]=\"disabled()\"\n [centerDetent]=\"true\"\n [detentValue]=\"0\"\n label=\"\"\n [showValue]=\"false\"\n ></tw-volume-dial>\n <span class=\"text-[9px] text-slate-500 font-mono\">{{ formatGain(inputGain()) }}dB</span>\n <span class=\"text-[8px] text-slate-600\">GAIN</span>\n </div>\n }\n\n <!-- Record Button -->\n @if (showRecord()) {\n <button\n type=\"button\"\n [class]=\"buttonSize()\"\n class=\"rounded-full flex items-center justify-center font-bold transition-all\"\n [class.bg-red-600]=\"record()\"\n [class.text-white]=\"record()\"\n [class.bg-slate-700]=\"!record()\"\n [class.text-slate-400]=\"!record()\"\n [class.hover:bg-red-500]=\"!record()\"\n [class.animate-pulse]=\"record()\"\n [disabled]=\"disabled()\"\n (click)=\"toggleRecord()\"\n title=\"Record Arm\"\n >\n R\n </button>\n }\n\n <!-- Aux Send Knobs -->\n @if (showAuxSends()) {\n <div class=\"flex flex-col gap-1 w-full border-t border-slate-700/50 pt-2\">\n <span class=\"text-[8px] text-slate-500 text-center\">SENDS</span>\n <div\n class=\"grid gap-1\"\n [class.grid-cols-2]=\"auxSendCount() > 2\"\n [class.grid-cols-1]=\"auxSendCount() <= 2\"\n >\n @for (aux of auxSendArray(); track aux.index) {\n <div class=\"flex flex-col items-center\">\n <tw-volume-dial\n [ngModel]=\"aux.value\"\n (ngModelChange)=\"onAuxSendChange(aux.index, $event)\"\n [min]=\"0\"\n [max]=\"100\"\n [step]=\"1\"\n size=\"xs\"\n [variant]=\"variant() === 'vintage' ? 'vintage' : 'minimal'\"\n [disabled]=\"disabled() || mute()\"\n label=\"\"\n [showValue]=\"false\"\n ></tw-volume-dial>\n <span class=\"text-[8px] text-slate-500 truncate max-w-full\">{{ aux.label }}</span>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- VU Meter -->\n @if (showMeter()) {\n <div class=\"flex-1 flex items-center justify-center py-1\">\n @if (stereo()) {\n <tw-vu-meter\n [leftValue]=\"meterLevel()\"\n [rightValue]=\"meterLevelRight()\"\n [stereo]=\"true\"\n [segmentCount]=\"size() === 'sm' ? 8 : 12\"\n [height]=\"size() === 'sm' ? 60 : size() === 'lg' ? 100 : 80\"\n variant=\"led\"\n ></tw-vu-meter>\n } @else {\n <tw-vu-meter\n [value]=\"meterLevel()\"\n [segmentCount]=\"size() === 'sm' ? 8 : 12\"\n [height]=\"size() === 'sm' ? 60 : size() === 'lg' ? 100 : 80\"\n variant=\"led\"\n ></tw-vu-meter>\n }\n </div>\n }\n\n <!-- Volume Fader / Dial -->\n <tw-volume-dial\n [ngModel]=\"volume()\"\n (ngModelChange)=\"onVolumeChange($event)\"\n [min]=\"0\"\n [max]=\"100\"\n [step]=\"1\"\n [size]=\"dialSize()\"\n [variant]=\"variant() === 'vintage' ? 'vintage' : 'modern'\"\n [disabled]=\"disabled() || mute()\"\n label=\"\"\n [showValue]=\"size() !== 'sm'\"\n ></tw-volume-dial>\n\n <!-- Pan Control -->\n @if (showPan()) {\n <tw-volume-dial\n [ngModel]=\"pan()\"\n (ngModelChange)=\"onPanChange($event)\"\n [min]=\"-100\"\n [max]=\"100\"\n [step]=\"1\"\n [size]=\"size() === 'lg' ? 'md' : 'sm'\"\n [variant]=\"variant() === 'vintage' ? 'vintage' : 'minimal'\"\n [disabled]=\"disabled()\"\n [centerDetent]=\"true\"\n [detentValue]=\"0\"\n label=\"\"\n [showValue]=\"false\"\n ></tw-volume-dial>\n <span class=\"text-[10px] text-slate-500\">PAN</span>\n }\n\n <!-- Mute / Solo Buttons -->\n @if (showMuteSolo()) {\n <div class=\"flex gap-1\">\n <button\n type=\"button\"\n [class]=\"buttonSize()\"\n class=\"rounded flex items-center justify-center font-bold transition-all\"\n [class.bg-amber-500]=\"mute()\"\n [class.text-black]=\"mute()\"\n [class.bg-slate-700]=\"!mute()\"\n [class.text-slate-400]=\"!mute()\"\n [class.hover:bg-amber-400]=\"!mute()\"\n [disabled]=\"disabled()\"\n (click)=\"toggleMute()\"\n title=\"Mute\"\n >\n M\n </button>\n <button\n type=\"button\"\n [class]=\"buttonSize()\"\n class=\"rounded flex items-center justify-center font-bold transition-all\"\n [class.bg-green-500]=\"solo()\"\n [class.text-black]=\"solo()\"\n [class.bg-slate-700]=\"!solo()\"\n [class.text-slate-400]=\"!solo()\"\n [class.hover:bg-green-400]=\"!solo()\"\n [disabled]=\"disabled()\"\n (click)=\"toggleSolo()\"\n title=\"Solo\"\n >\n S\n </button>\n </div>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: TwVolumeDialComponent, selector: "tw-volume-dial", inputs: ["
|
|
19136
|
+
], ngImport: i0, template: "<div [class]=\"containerClasses()\">\n <!-- Channel Label with Signal Indicator -->\n @if (showLabel()) {\n <div [class]=\"labelClasses()\" class=\"relative flex items-center justify-center gap-1\">\n <!-- Signal Present Indicator -->\n @if (showSignalIndicator()) {\n <div\n class=\"w-2 h-2 rounded-full transition-all duration-150\"\n [class.bg-green-500]=\"signalPresent()\"\n [class.shadow-[0_0_6px_rgba(34,197,94,0.8)]]=\"signalPresent()\"\n [class.bg-slate-600]=\"!signalPresent()\"\n title=\"Signal Present\"\n ></div>\n }\n <span class=\"text-slate-400\">{{ channelNumber() }}</span>\n <span class=\"text-white\">{{ label() }}</span>\n </div>\n }\n\n <!-- Input Gain Control -->\n @if (showInputGain()) {\n <div class=\"flex flex-col items-center gap-1\">\n <tw-volume-dial\n [ngModel]=\"inputGain()\"\n (ngModelChange)=\"onInputGainChange($event)\"\n [min]=\"-20\"\n [max]=\"20\"\n [step]=\"1\"\n [size]=\"size() === 'lg' ? 'sm' : 'xs'\"\n [variant]=\"variant() === 'vintage' ? 'vintage' : 'minimal'\"\n [disabled]=\"disabled()\"\n [centerDetent]=\"true\"\n [detentValue]=\"0\"\n label=\"\"\n [showValue]=\"false\"\n ></tw-volume-dial>\n <span class=\"text-[9px] text-slate-500 font-mono\">{{ formatGain(inputGain()) }}dB</span>\n <span class=\"text-[8px] text-slate-600\">GAIN</span>\n </div>\n }\n\n <!-- Record Button -->\n @if (showRecord()) {\n <button\n type=\"button\"\n [class]=\"buttonSize()\"\n class=\"rounded-full flex items-center justify-center font-bold transition-all\"\n [class.bg-red-600]=\"record()\"\n [class.text-white]=\"record()\"\n [class.bg-slate-700]=\"!record()\"\n [class.text-slate-400]=\"!record()\"\n [class.hover:bg-red-500]=\"!record()\"\n [class.animate-pulse]=\"record()\"\n [disabled]=\"disabled()\"\n (click)=\"toggleRecord()\"\n title=\"Record Arm\"\n >\n R\n </button>\n }\n\n <!-- Aux Send Knobs -->\n @if (showAuxSends()) {\n <div class=\"flex flex-col gap-1 w-full border-t border-slate-700/50 pt-2\">\n <span class=\"text-[8px] text-slate-500 text-center\">SENDS</span>\n <div\n class=\"grid gap-1\"\n [class.grid-cols-2]=\"auxSendCount() > 2\"\n [class.grid-cols-1]=\"auxSendCount() <= 2\"\n >\n @for (aux of auxSendArray(); track aux.index) {\n <div class=\"flex flex-col items-center\">\n <tw-volume-dial\n [ngModel]=\"aux.value\"\n (ngModelChange)=\"onAuxSendChange(aux.index, $event)\"\n [min]=\"0\"\n [max]=\"100\"\n [step]=\"1\"\n size=\"xs\"\n [variant]=\"variant() === 'vintage' ? 'vintage' : 'minimal'\"\n [disabled]=\"disabled() || mute()\"\n label=\"\"\n [showValue]=\"false\"\n ></tw-volume-dial>\n <span class=\"text-[8px] text-slate-500 truncate max-w-full\">{{ aux.label }}</span>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- VU Meter -->\n @if (showMeter()) {\n <div class=\"flex-1 flex items-center justify-center py-1\">\n @if (stereo()) {\n <tw-vu-meter\n [leftValue]=\"meterLevel()\"\n [rightValue]=\"meterLevelRight()\"\n [stereo]=\"true\"\n [segmentCount]=\"size() === 'sm' ? 8 : 12\"\n [height]=\"size() === 'sm' ? 60 : size() === 'lg' ? 100 : 80\"\n variant=\"led\"\n ></tw-vu-meter>\n } @else {\n <tw-vu-meter\n [value]=\"meterLevel()\"\n [segmentCount]=\"size() === 'sm' ? 8 : 12\"\n [height]=\"size() === 'sm' ? 60 : size() === 'lg' ? 100 : 80\"\n variant=\"led\"\n ></tw-vu-meter>\n }\n </div>\n }\n\n <!-- Volume Fader / Dial -->\n <tw-volume-dial\n [ngModel]=\"volume()\"\n (ngModelChange)=\"onVolumeChange($event)\"\n [min]=\"0\"\n [max]=\"100\"\n [step]=\"1\"\n [size]=\"dialSize()\"\n [variant]=\"variant() === 'vintage' ? 'vintage' : 'modern'\"\n [disabled]=\"disabled() || mute()\"\n label=\"\"\n [showValue]=\"size() !== 'sm'\"\n ></tw-volume-dial>\n\n <!-- Pan Control -->\n @if (showPan()) {\n <tw-volume-dial\n [ngModel]=\"pan()\"\n (ngModelChange)=\"onPanChange($event)\"\n [min]=\"-100\"\n [max]=\"100\"\n [step]=\"1\"\n [size]=\"size() === 'lg' ? 'md' : 'sm'\"\n [variant]=\"variant() === 'vintage' ? 'vintage' : 'minimal'\"\n [disabled]=\"disabled()\"\n [centerDetent]=\"true\"\n [detentValue]=\"0\"\n label=\"\"\n [showValue]=\"false\"\n ></tw-volume-dial>\n <span class=\"text-[10px] text-slate-500\">PAN</span>\n }\n\n <!-- Mute / Solo Buttons -->\n @if (showMuteSolo()) {\n <div class=\"flex gap-1\">\n <button\n type=\"button\"\n [class]=\"buttonSize()\"\n class=\"rounded flex items-center justify-center font-bold transition-all\"\n [class.bg-amber-500]=\"mute()\"\n [class.text-black]=\"mute()\"\n [class.bg-slate-700]=\"!mute()\"\n [class.text-slate-400]=\"!mute()\"\n [class.hover:bg-amber-400]=\"!mute()\"\n [disabled]=\"disabled()\"\n (click)=\"toggleMute()\"\n title=\"Mute\"\n >\n M\n </button>\n <button\n type=\"button\"\n [class]=\"buttonSize()\"\n class=\"rounded flex items-center justify-center font-bold transition-all\"\n [class.bg-green-500]=\"solo()\"\n [class.text-black]=\"solo()\"\n [class.bg-slate-700]=\"!solo()\"\n [class.text-slate-400]=\"!solo()\"\n [class.hover:bg-green-400]=\"!solo()\"\n [disabled]=\"disabled()\"\n (click)=\"toggleSolo()\"\n title=\"Solo\"\n >\n S\n </button>\n </div>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: TwVolumeDialComponent, selector: "tw-volume-dial", inputs: ["min", "max", "step", "variant", "size", "disabled", "showValue", "showTicks", "showLabel", "showLedRing", "label", "unit", "centerDetent", "detentValue", "classOverride", "customSize", "customStrokeWidth", "hapticFeedback", "touchGuard", "minTouchDuration", "announceChanges", "reducedMotion"], outputs: ["valueChange", "hapticTrigger"] }, { kind: "component", type: TwVuMeterComponent, selector: "tw-vu-meter", inputs: ["value", "leftValue", "rightValue", "min", "max", "stereo", "variant", "orientation", "meterMode", "segmentCount", "height", "width", "barWidth", "gapSize", "rmsDecayRate", "customHeight", "customWidth", "customBarWidth", "customGapSize", "showPeak", "peakHoldTime", "peakDecayRate", "showClip", "clipThreshold", "showScale", "showChannelLabels", "label", "labelPosition", "yellowThreshold", "redThreshold", "classOverride"], outputs: ["clipDetected"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
19139
19137
|
}
|
|
19140
19138
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TwChannelStripComponent, decorators: [{
|
|
19141
19139
|
type: Component,
|
|
@@ -40180,7 +40178,7 @@ class TwTerminalComponent {
|
|
|
40180
40178
|
// Computed classes
|
|
40181
40179
|
containerClasses = computed(() => {
|
|
40182
40180
|
const variant = this.variant();
|
|
40183
|
-
const base = 'flex flex-col h-full overflow-hidden';
|
|
40181
|
+
const base = 'flex flex-col h-full overflow-hidden rounded-lg';
|
|
40184
40182
|
const variantClasses = {
|
|
40185
40183
|
default: 'bg-gray-900 text-gray-100',
|
|
40186
40184
|
dark: 'bg-black text-gray-200',
|
|
@@ -40339,7 +40337,7 @@ class TwTerminalComponent {
|
|
|
40339
40337
|
<!-- Input area -->
|
|
40340
40338
|
@if (showInput()) {
|
|
40341
40339
|
<div
|
|
40342
|
-
class="flex items-center gap-2 px-4 py-2 border-t border-gray-700 bg-gray-800"
|
|
40340
|
+
class="flex items-center gap-2 px-4 py-2 border-t border-gray-700 bg-gray-800 rounded-b-lg"
|
|
40343
40341
|
>
|
|
40344
40342
|
<span class="text-green-400 font-mono">{{ prompt() }}</span>
|
|
40345
40343
|
<input
|
|
@@ -40437,7 +40435,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
40437
40435
|
<!-- Input area -->
|
|
40438
40436
|
@if (showInput()) {
|
|
40439
40437
|
<div
|
|
40440
|
-
class="flex items-center gap-2 px-4 py-2 border-t border-gray-700 bg-gray-800"
|
|
40438
|
+
class="flex items-center gap-2 px-4 py-2 border-t border-gray-700 bg-gray-800 rounded-b-lg"
|
|
40441
40439
|
>
|
|
40442
40440
|
<span class="text-green-400 font-mono">{{ prompt() }}</span>
|
|
40443
40441
|
<input
|
|
@@ -40567,7 +40565,7 @@ class TwLogViewerComponent {
|
|
|
40567
40565
|
}
|
|
40568
40566
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TwLogViewerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
40569
40567
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: TwLogViewerComponent, isStandalone: true, selector: "tw-log-viewer", inputs: { entries: { classPropertyName: "entries", publicName: "entries", isSignal: true, isRequired: false, transformFunction: null }, showSource: { classPropertyName: "showSource", publicName: "showSource", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { entrySelect: "entrySelect", clearLogs: "clearLogs", exportClick: "exportClick" }, host: { classAttribute: "tw-log-viewer block" }, ngImport: i0, template: `
|
|
40570
|
-
<div class="flex flex-col h-full bg-white dark:bg-gray-900 overflow-hidden">
|
|
40568
|
+
<div class="flex flex-col h-full bg-white dark:bg-gray-900 rounded-lg overflow-hidden">
|
|
40571
40569
|
<!-- Toolbar -->
|
|
40572
40570
|
<div
|
|
40573
40571
|
class="flex items-center gap-2 px-3 py-2 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-800"
|
|
@@ -40717,7 +40715,7 @@ class TwLogViewerComponent {
|
|
|
40717
40715
|
|
|
40718
40716
|
<!-- Status bar -->
|
|
40719
40717
|
<div
|
|
40720
|
-
class="flex items-center justify-between px-3 py-1.5 text-xs text-gray-500 dark:text-gray-400 border-t border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-800"
|
|
40718
|
+
class="flex items-center justify-between px-3 py-1.5 text-xs text-gray-500 dark:text-gray-400 border-t border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-800 rounded-b-lg"
|
|
40721
40719
|
>
|
|
40722
40720
|
<span>{{ filteredEntries().length }} / {{ entries().length }} entries</span>
|
|
40723
40721
|
<span>
|
|
@@ -40738,7 +40736,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
40738
40736
|
standalone: true,
|
|
40739
40737
|
imports: [CommonModule, FormsModule],
|
|
40740
40738
|
template: `
|
|
40741
|
-
<div class="flex flex-col h-full bg-white dark:bg-gray-900 overflow-hidden">
|
|
40739
|
+
<div class="flex flex-col h-full bg-white dark:bg-gray-900 rounded-lg overflow-hidden">
|
|
40742
40740
|
<!-- Toolbar -->
|
|
40743
40741
|
<div
|
|
40744
40742
|
class="flex items-center gap-2 px-3 py-2 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-800"
|
|
@@ -40888,7 +40886,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
40888
40886
|
|
|
40889
40887
|
<!-- Status bar -->
|
|
40890
40888
|
<div
|
|
40891
|
-
class="flex items-center justify-between px-3 py-1.5 text-xs text-gray-500 dark:text-gray-400 border-t border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-800"
|
|
40889
|
+
class="flex items-center justify-between px-3 py-1.5 text-xs text-gray-500 dark:text-gray-400 border-t border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-800 rounded-b-lg"
|
|
40892
40890
|
>
|
|
40893
40891
|
<span>{{ filteredEntries().length }} / {{ entries().length }} entries</span>
|
|
40894
40892
|
<span>
|
|
@@ -43424,149 +43422,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
43424
43422
|
args: [{ providedIn: 'root' }]
|
|
43425
43423
|
}], ctorParameters: () => [] });
|
|
43426
43424
|
|
|
43427
|
-
/**
|
|
43428
|
-
* Dynamic import utilities that prevent bundlers from analyzing/resolving the imports at build time.
|
|
43429
|
-
*
|
|
43430
|
-
* The trick is to use a variable for the module specifier, which makes it impossible for bundlers
|
|
43431
|
-
* to statically analyze the import. This is intentional for optional dependencies like Electron and Tauri.
|
|
43432
|
-
*/
|
|
43433
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
43434
|
-
/**
|
|
43435
|
-
* Creates a dynamic import function that bundlers cannot statically analyze.
|
|
43436
|
-
* This prevents build errors for optional dependencies that may not be installed.
|
|
43437
|
-
*/
|
|
43438
|
-
function createDynamicImport() {
|
|
43439
|
-
// Use Function constructor to create import at runtime, preventing static analysis
|
|
43440
|
-
return new Function('modulePath', 'return import(modulePath)');
|
|
43441
|
-
}
|
|
43442
|
-
const dynamicImport = createDynamicImport();
|
|
43443
|
-
/**
|
|
43444
|
-
* Dynamically import the Electron module.
|
|
43445
|
-
* This will only work at runtime when running in an Electron context.
|
|
43446
|
-
* Returns null if Electron is not available.
|
|
43447
|
-
*/
|
|
43448
|
-
async function importElectron() {
|
|
43449
|
-
try {
|
|
43450
|
-
const electron = await dynamicImport('electron');
|
|
43451
|
-
return electron;
|
|
43452
|
-
}
|
|
43453
|
-
catch {
|
|
43454
|
-
return null;
|
|
43455
|
-
}
|
|
43456
|
-
}
|
|
43457
|
-
/**
|
|
43458
|
-
* Dynamically import Tauri dialog plugin.
|
|
43459
|
-
* This will only work at runtime when running in a Tauri context.
|
|
43460
|
-
* Returns null if Tauri dialog is not available.
|
|
43461
|
-
*/
|
|
43462
|
-
async function importTauriDialog() {
|
|
43463
|
-
try {
|
|
43464
|
-
const dialog = await dynamicImport('@tauri-apps/plugin-dialog');
|
|
43465
|
-
return dialog;
|
|
43466
|
-
}
|
|
43467
|
-
catch {
|
|
43468
|
-
return null;
|
|
43469
|
-
}
|
|
43470
|
-
}
|
|
43471
|
-
/**
|
|
43472
|
-
* Dynamically import Tauri notification plugin.
|
|
43473
|
-
* This will only work at runtime when running in a Tauri context.
|
|
43474
|
-
* Returns null if Tauri notification is not available.
|
|
43475
|
-
*/
|
|
43476
|
-
async function importTauriNotification() {
|
|
43477
|
-
try {
|
|
43478
|
-
const notification = await dynamicImport('@tauri-apps/plugin-notification');
|
|
43479
|
-
return notification;
|
|
43480
|
-
}
|
|
43481
|
-
catch {
|
|
43482
|
-
return null;
|
|
43483
|
-
}
|
|
43484
|
-
}
|
|
43485
|
-
/**
|
|
43486
|
-
* Dynamically import Tauri process plugin.
|
|
43487
|
-
* This will only work at runtime when running in a Tauri context.
|
|
43488
|
-
* Returns null if Tauri process is not available.
|
|
43489
|
-
*/
|
|
43490
|
-
async function importTauriProcess() {
|
|
43491
|
-
try {
|
|
43492
|
-
const process = await dynamicImport('@tauri-apps/plugin-process');
|
|
43493
|
-
return process;
|
|
43494
|
-
}
|
|
43495
|
-
catch {
|
|
43496
|
-
return null;
|
|
43497
|
-
}
|
|
43498
|
-
}
|
|
43499
|
-
/**
|
|
43500
|
-
* Dynamically import Tauri updater plugin.
|
|
43501
|
-
* This will only work at runtime when running in a Tauri context.
|
|
43502
|
-
* Returns null if Tauri updater is not available.
|
|
43503
|
-
*/
|
|
43504
|
-
async function importTauriUpdater() {
|
|
43505
|
-
try {
|
|
43506
|
-
const updater = await dynamicImport('@tauri-apps/plugin-updater');
|
|
43507
|
-
return updater;
|
|
43508
|
-
}
|
|
43509
|
-
catch {
|
|
43510
|
-
return null;
|
|
43511
|
-
}
|
|
43512
|
-
}
|
|
43513
|
-
/**
|
|
43514
|
-
* Dynamically import Tauri app API.
|
|
43515
|
-
* This will only work at runtime when running in a Tauri context.
|
|
43516
|
-
* Returns null if Tauri app is not available.
|
|
43517
|
-
*/
|
|
43518
|
-
async function importTauriApp() {
|
|
43519
|
-
try {
|
|
43520
|
-
const app = await dynamicImport('@tauri-apps/api/app');
|
|
43521
|
-
return app;
|
|
43522
|
-
}
|
|
43523
|
-
catch {
|
|
43524
|
-
return null;
|
|
43525
|
-
}
|
|
43526
|
-
}
|
|
43527
|
-
/**
|
|
43528
|
-
* Dynamically import Tauri menu API.
|
|
43529
|
-
* This will only work at runtime when running in a Tauri context.
|
|
43530
|
-
* Returns null if Tauri menu is not available.
|
|
43531
|
-
*/
|
|
43532
|
-
async function importTauriMenu() {
|
|
43533
|
-
try {
|
|
43534
|
-
const menu = await dynamicImport('@tauri-apps/api/menu');
|
|
43535
|
-
return menu;
|
|
43536
|
-
}
|
|
43537
|
-
catch {
|
|
43538
|
-
return null;
|
|
43539
|
-
}
|
|
43540
|
-
}
|
|
43541
|
-
/**
|
|
43542
|
-
* Dynamically import Tauri tray API.
|
|
43543
|
-
* This will only work at runtime when running in a Tauri context.
|
|
43544
|
-
* Returns null if Tauri tray is not available.
|
|
43545
|
-
*/
|
|
43546
|
-
async function importTauriTray() {
|
|
43547
|
-
try {
|
|
43548
|
-
const tray = await dynamicImport('@tauri-apps/api/tray');
|
|
43549
|
-
return tray;
|
|
43550
|
-
}
|
|
43551
|
-
catch {
|
|
43552
|
-
return null;
|
|
43553
|
-
}
|
|
43554
|
-
}
|
|
43555
|
-
/**
|
|
43556
|
-
* Dynamically import Tauri window API.
|
|
43557
|
-
* This will only work at runtime when running in a Tauri context.
|
|
43558
|
-
* Returns null if Tauri window is not available.
|
|
43559
|
-
*/
|
|
43560
|
-
async function importTauriWindow() {
|
|
43561
|
-
try {
|
|
43562
|
-
const window = await dynamicImport('@tauri-apps/api/window');
|
|
43563
|
-
return window;
|
|
43564
|
-
}
|
|
43565
|
-
catch {
|
|
43566
|
-
return null;
|
|
43567
|
-
}
|
|
43568
|
-
}
|
|
43569
|
-
|
|
43570
43425
|
const PLATFORM_TAURI$4 = 'tauri';
|
|
43571
43426
|
const PLATFORM_ELECTRON$4 = 'electron';
|
|
43572
43427
|
class FilePickerService {
|
|
@@ -43609,14 +43464,12 @@ class FilePickerService {
|
|
|
43609
43464
|
}
|
|
43610
43465
|
async openFileTauri(options) {
|
|
43611
43466
|
try {
|
|
43612
|
-
const
|
|
43613
|
-
if (!dialog)
|
|
43614
|
-
return null;
|
|
43467
|
+
const { open } = await import('@tauri-apps/plugin-dialog');
|
|
43615
43468
|
const filters = options.filters?.map(f => ({
|
|
43616
43469
|
name: f.name,
|
|
43617
43470
|
extensions: f.extensions,
|
|
43618
43471
|
}));
|
|
43619
|
-
const result = await
|
|
43472
|
+
const result = await open({
|
|
43620
43473
|
title: options.title,
|
|
43621
43474
|
defaultPath: options.defaultPath,
|
|
43622
43475
|
filters,
|
|
@@ -43640,10 +43493,8 @@ class FilePickerService {
|
|
|
43640
43493
|
}
|
|
43641
43494
|
async openFileElectron(options) {
|
|
43642
43495
|
try {
|
|
43643
|
-
const
|
|
43644
|
-
|
|
43645
|
-
return null;
|
|
43646
|
-
const result = await electron.ipcRenderer.invoke('show-open-dialog', {
|
|
43496
|
+
const { ipcRenderer } = await import('electron');
|
|
43497
|
+
const result = await ipcRenderer.invoke('show-open-dialog', {
|
|
43647
43498
|
title: options.title,
|
|
43648
43499
|
defaultPath: options.defaultPath,
|
|
43649
43500
|
properties: [
|
|
@@ -43703,14 +43554,12 @@ class FilePickerService {
|
|
|
43703
43554
|
}
|
|
43704
43555
|
async saveFileTauri(options) {
|
|
43705
43556
|
try {
|
|
43706
|
-
const
|
|
43707
|
-
if (!dialog)
|
|
43708
|
-
return null;
|
|
43557
|
+
const { save } = await import('@tauri-apps/plugin-dialog');
|
|
43709
43558
|
const filters = options.filters?.map(f => ({
|
|
43710
43559
|
name: f.name,
|
|
43711
43560
|
extensions: f.extensions,
|
|
43712
43561
|
}));
|
|
43713
|
-
const result = await
|
|
43562
|
+
const result = await save({
|
|
43714
43563
|
title: options.title,
|
|
43715
43564
|
defaultPath: options.defaultPath,
|
|
43716
43565
|
filters,
|
|
@@ -43724,10 +43573,8 @@ class FilePickerService {
|
|
|
43724
43573
|
}
|
|
43725
43574
|
async saveFileElectron(options) {
|
|
43726
43575
|
try {
|
|
43727
|
-
const
|
|
43728
|
-
|
|
43729
|
-
return null;
|
|
43730
|
-
const result = await electron.ipcRenderer.invoke('show-save-dialog', {
|
|
43576
|
+
const { ipcRenderer } = await import('electron');
|
|
43577
|
+
const result = await ipcRenderer.invoke('show-save-dialog', {
|
|
43731
43578
|
title: options.title,
|
|
43732
43579
|
defaultPath: options.defaultPath,
|
|
43733
43580
|
filters: options.filters?.map(f => ({
|
|
@@ -43751,10 +43598,8 @@ class FilePickerService {
|
|
|
43751
43598
|
}
|
|
43752
43599
|
async selectDirectoryTauri(options) {
|
|
43753
43600
|
try {
|
|
43754
|
-
const
|
|
43755
|
-
|
|
43756
|
-
return null;
|
|
43757
|
-
const result = await dialog.open({
|
|
43601
|
+
const { open } = await import('@tauri-apps/plugin-dialog');
|
|
43602
|
+
const result = await open({
|
|
43758
43603
|
title: options.title,
|
|
43759
43604
|
defaultPath: options.defaultPath,
|
|
43760
43605
|
directory: true,
|
|
@@ -43770,10 +43615,8 @@ class FilePickerService {
|
|
|
43770
43615
|
}
|
|
43771
43616
|
async selectDirectoryElectron(options) {
|
|
43772
43617
|
try {
|
|
43773
|
-
const
|
|
43774
|
-
|
|
43775
|
-
return null;
|
|
43776
|
-
const result = await electron.ipcRenderer.invoke('show-open-dialog', {
|
|
43618
|
+
const { ipcRenderer } = await import('electron');
|
|
43619
|
+
const result = await ipcRenderer.invoke('show-open-dialog', {
|
|
43777
43620
|
title: options.title,
|
|
43778
43621
|
defaultPath: options.defaultPath,
|
|
43779
43622
|
properties: ['openDirectory'],
|
|
@@ -43861,8 +43704,8 @@ class SystemTrayService {
|
|
|
43861
43704
|
await tray.setIcon(icon);
|
|
43862
43705
|
}
|
|
43863
43706
|
else if (platform === PLATFORM_ELECTRON$3) {
|
|
43864
|
-
const
|
|
43865
|
-
|
|
43707
|
+
const { ipcRenderer } = await import('electron');
|
|
43708
|
+
ipcRenderer.send('tray-set-icon', icon);
|
|
43866
43709
|
}
|
|
43867
43710
|
}
|
|
43868
43711
|
async setTooltip(tooltip) {
|
|
@@ -43872,8 +43715,8 @@ class SystemTrayService {
|
|
|
43872
43715
|
await tray.setTooltip(tooltip);
|
|
43873
43716
|
}
|
|
43874
43717
|
else if (platform === PLATFORM_ELECTRON$3) {
|
|
43875
|
-
const
|
|
43876
|
-
|
|
43718
|
+
const { ipcRenderer } = await import('electron');
|
|
43719
|
+
ipcRenderer.send('tray-set-tooltip', tooltip);
|
|
43877
43720
|
}
|
|
43878
43721
|
}
|
|
43879
43722
|
async setMenu(menu) {
|
|
@@ -43882,8 +43725,8 @@ class SystemTrayService {
|
|
|
43882
43725
|
await this.setTauriMenu(menu);
|
|
43883
43726
|
}
|
|
43884
43727
|
else if (platform === PLATFORM_ELECTRON$3) {
|
|
43885
|
-
const
|
|
43886
|
-
|
|
43728
|
+
const { ipcRenderer } = await import('electron');
|
|
43729
|
+
ipcRenderer.send('tray-set-menu', this.convertMenuForElectron(menu));
|
|
43887
43730
|
}
|
|
43888
43731
|
}
|
|
43889
43732
|
async destroy() {
|
|
@@ -43892,16 +43735,14 @@ class SystemTrayService {
|
|
|
43892
43735
|
this.trayInstance = null;
|
|
43893
43736
|
}
|
|
43894
43737
|
else if (platform === PLATFORM_ELECTRON$3) {
|
|
43895
|
-
const
|
|
43896
|
-
|
|
43738
|
+
const { ipcRenderer } = await import('electron');
|
|
43739
|
+
ipcRenderer.send('tray-destroy');
|
|
43897
43740
|
}
|
|
43898
43741
|
this.isVisible.set(false);
|
|
43899
43742
|
}
|
|
43900
43743
|
async createTauriTray(config) {
|
|
43901
43744
|
try {
|
|
43902
|
-
const tauriTray = await
|
|
43903
|
-
if (!tauriTray)
|
|
43904
|
-
return false;
|
|
43745
|
+
const tauriTray = await import('@tauri-apps/api/tray');
|
|
43905
43746
|
this.trayInstance = await tauriTray.TrayIcon.new({
|
|
43906
43747
|
icon: config.icon,
|
|
43907
43748
|
tooltip: config.tooltip,
|
|
@@ -43920,10 +43761,8 @@ class SystemTrayService {
|
|
|
43920
43761
|
}
|
|
43921
43762
|
async createElectronTray(config) {
|
|
43922
43763
|
try {
|
|
43923
|
-
const
|
|
43924
|
-
|
|
43925
|
-
return false;
|
|
43926
|
-
await electron.ipcRenderer.invoke('tray-create', {
|
|
43764
|
+
const { ipcRenderer } = await import('electron');
|
|
43765
|
+
await ipcRenderer.invoke('tray-create', {
|
|
43927
43766
|
icon: config.icon,
|
|
43928
43767
|
tooltip: config.tooltip,
|
|
43929
43768
|
menu: config.menu ? this.convertMenuForElectron(config.menu) : undefined,
|
|
@@ -43938,9 +43777,7 @@ class SystemTrayService {
|
|
|
43938
43777
|
}
|
|
43939
43778
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
43940
43779
|
async buildTauriMenu(items) {
|
|
43941
|
-
const tauriMenu = await
|
|
43942
|
-
if (!tauriMenu)
|
|
43943
|
-
return null;
|
|
43780
|
+
const tauriMenu = await import('@tauri-apps/api/menu');
|
|
43944
43781
|
const { Menu, MenuItem, Submenu } = tauriMenu;
|
|
43945
43782
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
43946
43783
|
const menuItems = [];
|
|
@@ -44027,9 +43864,7 @@ class NativeNotificationsService {
|
|
|
44027
43864
|
const platform = this.platformService.platform();
|
|
44028
43865
|
if (platform === PLATFORM_TAURI$2) {
|
|
44029
43866
|
try {
|
|
44030
|
-
const notification = await
|
|
44031
|
-
if (!notification)
|
|
44032
|
-
return false;
|
|
43867
|
+
const notification = await import('@tauri-apps/plugin-notification');
|
|
44033
43868
|
let granted = await notification.isPermissionGranted();
|
|
44034
43869
|
if (!granted) {
|
|
44035
43870
|
const result = await notification.requestPermission();
|
|
@@ -44080,8 +43915,8 @@ class NativeNotificationsService {
|
|
|
44080
43915
|
}
|
|
44081
43916
|
else if (platform === PLATFORM_ELECTRON$2) {
|
|
44082
43917
|
try {
|
|
44083
|
-
const
|
|
44084
|
-
|
|
43918
|
+
const { ipcRenderer } = await import('electron');
|
|
43919
|
+
ipcRenderer.send('set-badge-count', count);
|
|
44085
43920
|
}
|
|
44086
43921
|
catch (error) {
|
|
44087
43922
|
console.error('Failed to set Electron badge count:', error);
|
|
@@ -44101,9 +43936,7 @@ class NativeNotificationsService {
|
|
|
44101
43936
|
}
|
|
44102
43937
|
async showTauriNotification(options) {
|
|
44103
43938
|
try {
|
|
44104
|
-
const notification = await
|
|
44105
|
-
if (!notification)
|
|
44106
|
-
return null;
|
|
43939
|
+
const notification = await import('@tauri-apps/plugin-notification');
|
|
44107
43940
|
const id = `notification-${Date.now()}`;
|
|
44108
43941
|
await notification.sendNotification({
|
|
44109
43942
|
title: options.title,
|
|
@@ -44119,11 +43952,9 @@ class NativeNotificationsService {
|
|
|
44119
43952
|
}
|
|
44120
43953
|
async showElectronNotification(options) {
|
|
44121
43954
|
try {
|
|
44122
|
-
const
|
|
44123
|
-
if (!electron?.ipcRenderer)
|
|
44124
|
-
return null;
|
|
43955
|
+
const { ipcRenderer } = await import('electron');
|
|
44125
43956
|
const id = `notification-${Date.now()}`;
|
|
44126
|
-
await
|
|
43957
|
+
await ipcRenderer.invoke('show-notification', {
|
|
44127
43958
|
title: options.title,
|
|
44128
43959
|
body: options.body,
|
|
44129
43960
|
icon: options.icon,
|
|
@@ -44185,16 +44016,11 @@ class DockService {
|
|
|
44185
44016
|
const platform = this.platformService.platform();
|
|
44186
44017
|
if (platform === PLATFORM_TAURI$1) {
|
|
44187
44018
|
try {
|
|
44188
|
-
const
|
|
44189
|
-
|
|
44190
|
-
|
|
44191
|
-
|
|
44192
|
-
|
|
44193
|
-
const currentTitle = await appWindow.title();
|
|
44194
|
-
// Remove any existing badge from title (e.g., "App (3)" -> "App")
|
|
44195
|
-
const baseTitle = currentTitle.replace(/\s*\(\d+\)\s*$/, '');
|
|
44196
|
-
const newTitle = text ? `${baseTitle} (${text})` : baseTitle;
|
|
44197
|
-
await appWindow.setTitle(newTitle);
|
|
44019
|
+
const { getCurrentWindow } = await import('@tauri-apps/api/window');
|
|
44020
|
+
// Tauri doesn't have direct dock badge API, use window title instead
|
|
44021
|
+
const appWindow = getCurrentWindow();
|
|
44022
|
+
// Badge functionality varies by platform in Tauri
|
|
44023
|
+
console.warn('Dock badge not directly supported in Tauri, consider using notifications');
|
|
44198
44024
|
}
|
|
44199
44025
|
catch (error) {
|
|
44200
44026
|
console.error('Failed to set Tauri dock badge:', error);
|
|
@@ -44202,8 +44028,8 @@ class DockService {
|
|
|
44202
44028
|
}
|
|
44203
44029
|
else if (platform === PLATFORM_ELECTRON$1) {
|
|
44204
44030
|
try {
|
|
44205
|
-
const
|
|
44206
|
-
|
|
44031
|
+
const { ipcRenderer } = await import('electron');
|
|
44032
|
+
ipcRenderer.send('set-dock-badge', text);
|
|
44207
44033
|
}
|
|
44208
44034
|
catch (error) {
|
|
44209
44035
|
console.error('Failed to set Electron dock badge:', error);
|
|
@@ -44223,10 +44049,10 @@ class DockService {
|
|
|
44223
44049
|
const platform = this.platformService.platform();
|
|
44224
44050
|
if (platform === PLATFORM_ELECTRON$1) {
|
|
44225
44051
|
try {
|
|
44226
|
-
const
|
|
44052
|
+
const { ipcRenderer } = await import('electron');
|
|
44227
44053
|
// Progress should be between 0 and 1, or -1 to clear
|
|
44228
44054
|
const normalizedProgress = progress < 0 ? -1 : Math.min(1, Math.max(0, progress / 100));
|
|
44229
|
-
|
|
44055
|
+
ipcRenderer.send('set-progress', normalizedProgress);
|
|
44230
44056
|
}
|
|
44231
44057
|
catch (error) {
|
|
44232
44058
|
console.error('Failed to set Electron progress:', error);
|
|
@@ -44247,10 +44073,8 @@ class DockService {
|
|
|
44247
44073
|
const platform = this.platformService.platform();
|
|
44248
44074
|
if (platform === PLATFORM_ELECTRON$1) {
|
|
44249
44075
|
try {
|
|
44250
|
-
const
|
|
44251
|
-
|
|
44252
|
-
return -1;
|
|
44253
|
-
return await electron.ipcRenderer.invoke('dock-bounce', type);
|
|
44076
|
+
const { ipcRenderer } = await import('electron');
|
|
44077
|
+
return await ipcRenderer.invoke('dock-bounce', type);
|
|
44254
44078
|
}
|
|
44255
44079
|
catch (error) {
|
|
44256
44080
|
console.error('Failed to bounce Electron dock:', error);
|
|
@@ -44266,8 +44090,8 @@ class DockService {
|
|
|
44266
44090
|
const platform = this.platformService.platform();
|
|
44267
44091
|
if (platform === PLATFORM_ELECTRON$1) {
|
|
44268
44092
|
try {
|
|
44269
|
-
const
|
|
44270
|
-
|
|
44093
|
+
const { ipcRenderer } = await import('electron');
|
|
44094
|
+
ipcRenderer.send('cancel-dock-bounce', id);
|
|
44271
44095
|
}
|
|
44272
44096
|
catch (error) {
|
|
44273
44097
|
console.error('Failed to cancel Electron dock bounce:', error);
|
|
@@ -44281,8 +44105,8 @@ class DockService {
|
|
|
44281
44105
|
const platform = this.platformService.platform();
|
|
44282
44106
|
if (platform === PLATFORM_ELECTRON$1) {
|
|
44283
44107
|
try {
|
|
44284
|
-
const
|
|
44285
|
-
|
|
44108
|
+
const { ipcRenderer } = await import('electron');
|
|
44109
|
+
ipcRenderer.send('set-dock-menu', this.convertMenuForElectron(items));
|
|
44286
44110
|
}
|
|
44287
44111
|
catch (error) {
|
|
44288
44112
|
console.error('Failed to set Electron dock menu:', error);
|
|
@@ -44296,8 +44120,8 @@ class DockService {
|
|
|
44296
44120
|
const platform = this.platformService.platform();
|
|
44297
44121
|
if (platform === PLATFORM_ELECTRON$1) {
|
|
44298
44122
|
try {
|
|
44299
|
-
const
|
|
44300
|
-
|
|
44123
|
+
const { ipcRenderer } = await import('electron');
|
|
44124
|
+
ipcRenderer.send('show-dock');
|
|
44301
44125
|
}
|
|
44302
44126
|
catch (error) {
|
|
44303
44127
|
console.error('Failed to show Electron dock:', error);
|
|
@@ -44311,8 +44135,8 @@ class DockService {
|
|
|
44311
44135
|
const platform = this.platformService.platform();
|
|
44312
44136
|
if (platform === PLATFORM_ELECTRON$1) {
|
|
44313
44137
|
try {
|
|
44314
|
-
const
|
|
44315
|
-
|
|
44138
|
+
const { ipcRenderer } = await import('electron');
|
|
44139
|
+
ipcRenderer.send('hide-dock');
|
|
44316
44140
|
}
|
|
44317
44141
|
catch (error) {
|
|
44318
44142
|
console.error('Failed to hide Electron dock:', error);
|
|
@@ -44326,10 +44150,8 @@ class DockService {
|
|
|
44326
44150
|
const platform = this.platformService.platform();
|
|
44327
44151
|
if (platform === PLATFORM_TAURI$1) {
|
|
44328
44152
|
try {
|
|
44329
|
-
const
|
|
44330
|
-
|
|
44331
|
-
return;
|
|
44332
|
-
const appWindow = tauriWindow.getCurrentWindow();
|
|
44153
|
+
const { getCurrentWindow } = await import('@tauri-apps/api/window');
|
|
44154
|
+
const appWindow = getCurrentWindow();
|
|
44333
44155
|
await appWindow.requestUserAttention(flash ? 2 : null); // 2 = Informational
|
|
44334
44156
|
}
|
|
44335
44157
|
catch (error) {
|
|
@@ -44338,8 +44160,8 @@ class DockService {
|
|
|
44338
44160
|
}
|
|
44339
44161
|
else if (platform === PLATFORM_ELECTRON$1) {
|
|
44340
44162
|
try {
|
|
44341
|
-
const
|
|
44342
|
-
|
|
44163
|
+
const { ipcRenderer } = await import('electron');
|
|
44164
|
+
ipcRenderer.send('flash-frame', flash);
|
|
44343
44165
|
}
|
|
44344
44166
|
catch (error) {
|
|
44345
44167
|
console.error('Failed to flash Electron frame:', error);
|
|
@@ -44474,26 +44296,24 @@ class UpdateService {
|
|
|
44474
44296
|
}
|
|
44475
44297
|
async setupElectronListeners() {
|
|
44476
44298
|
try {
|
|
44477
|
-
const
|
|
44478
|
-
|
|
44479
|
-
return;
|
|
44480
|
-
electron.ipcRenderer.on('update-available', (_event, info) => {
|
|
44299
|
+
const { ipcRenderer } = await import('electron');
|
|
44300
|
+
ipcRenderer.on('update-available', (_event, info) => {
|
|
44481
44301
|
this.status.set('available');
|
|
44482
44302
|
this.updateInfo.set(info);
|
|
44483
44303
|
this.updateAvailable$.next(info);
|
|
44484
44304
|
});
|
|
44485
|
-
|
|
44305
|
+
ipcRenderer.on('update-not-available', () => {
|
|
44486
44306
|
this.status.set('not-available');
|
|
44487
44307
|
});
|
|
44488
|
-
|
|
44308
|
+
ipcRenderer.on('download-progress', (_event, progress) => {
|
|
44489
44309
|
this.progress.set(progress);
|
|
44490
44310
|
this.downloadProgress$.next(progress);
|
|
44491
44311
|
});
|
|
44492
|
-
|
|
44312
|
+
ipcRenderer.on('update-downloaded', () => {
|
|
44493
44313
|
this.status.set('downloaded');
|
|
44494
44314
|
this.updateDownloaded$.next();
|
|
44495
44315
|
});
|
|
44496
|
-
|
|
44316
|
+
ipcRenderer.on('update-error', (_event, error) => {
|
|
44497
44317
|
this.status.set('error');
|
|
44498
44318
|
this.error.set(error);
|
|
44499
44319
|
this.updateError$.next(error);
|
|
@@ -44504,10 +44324,8 @@ class UpdateService {
|
|
|
44504
44324
|
}
|
|
44505
44325
|
}
|
|
44506
44326
|
async checkTauriUpdates() {
|
|
44507
|
-
const updater = await
|
|
44508
|
-
const app = await
|
|
44509
|
-
if (!updater || !app)
|
|
44510
|
-
return null;
|
|
44327
|
+
const updater = await import('@tauri-apps/plugin-updater');
|
|
44328
|
+
const app = await import('@tauri-apps/api/app');
|
|
44511
44329
|
const currentVersion = await app.getVersion();
|
|
44512
44330
|
const update = await updater.check();
|
|
44513
44331
|
if (update?.available) {
|
|
@@ -44526,10 +44344,8 @@ class UpdateService {
|
|
|
44526
44344
|
return null;
|
|
44527
44345
|
}
|
|
44528
44346
|
async checkElectronUpdates() {
|
|
44529
|
-
const
|
|
44530
|
-
|
|
44531
|
-
return null;
|
|
44532
|
-
const result = (await electron.ipcRenderer.invoke('check-for-updates'));
|
|
44347
|
+
const { ipcRenderer } = await import('electron');
|
|
44348
|
+
const result = (await ipcRenderer.invoke('check-for-updates'));
|
|
44533
44349
|
if (result?.updateAvailable) {
|
|
44534
44350
|
const info = {
|
|
44535
44351
|
currentVersion: result.currentVersion || '',
|
|
@@ -44546,9 +44362,7 @@ class UpdateService {
|
|
|
44546
44362
|
return null;
|
|
44547
44363
|
}
|
|
44548
44364
|
async downloadTauriUpdate() {
|
|
44549
|
-
const updater = await
|
|
44550
|
-
if (!updater)
|
|
44551
|
-
return;
|
|
44365
|
+
const updater = await import('@tauri-apps/plugin-updater');
|
|
44552
44366
|
const update = await updater.check();
|
|
44553
44367
|
if (update?.available) {
|
|
44554
44368
|
await update.downloadAndInstall(event => {
|
|
@@ -44578,16 +44392,16 @@ class UpdateService {
|
|
|
44578
44392
|
}
|
|
44579
44393
|
}
|
|
44580
44394
|
async downloadElectronUpdate() {
|
|
44581
|
-
const
|
|
44582
|
-
|
|
44395
|
+
const { ipcRenderer } = await import('electron');
|
|
44396
|
+
ipcRenderer.send('download-update');
|
|
44583
44397
|
}
|
|
44584
44398
|
async installTauriUpdate() {
|
|
44585
|
-
const process = await
|
|
44586
|
-
await process
|
|
44399
|
+
const process = await import('@tauri-apps/plugin-process');
|
|
44400
|
+
await process.relaunch();
|
|
44587
44401
|
}
|
|
44588
44402
|
async installElectronUpdate() {
|
|
44589
|
-
const
|
|
44590
|
-
|
|
44403
|
+
const { ipcRenderer } = await import('electron');
|
|
44404
|
+
ipcRenderer.send('quit-and-install');
|
|
44591
44405
|
}
|
|
44592
44406
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: UpdateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
44593
44407
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: UpdateService, providedIn: 'root' });
|