= this.workContextService.activeWorkContext$.pipe(
- map((workContext) => !!workContext.isEnableBacklog),
+ isShowBacklog = toSignal(
+ this.workContextService.activeWorkContext$.pipe(
+ map((workContext) => !!workContext.isEnableBacklog),
+ ),
+ { initialValue: false },
);
+
+ backlogTasks = toSignal(this.workContextService.backlogTasks$, { initialValue: [] });
+ doneTasks = toSignal(this.workContextService.doneTasks$, { initialValue: [] });
+ undoneTasks = toSignal(this.workContextService.undoneTasks$, { initialValue: [] });
}
diff --git a/src/app/ui/dialog-unsplash-picker/dialog-unsplash-picker.component.ts b/src/app/ui/dialog-unsplash-picker/dialog-unsplash-picker.component.ts
index cf8879f0b..a06229888 100644
--- a/src/app/ui/dialog-unsplash-picker/dialog-unsplash-picker.component.ts
+++ b/src/app/ui/dialog-unsplash-picker/dialog-unsplash-picker.component.ts
@@ -19,13 +19,7 @@ import { MatProgressSpinner } from '@angular/material/progress-spinner';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { Subject } from 'rxjs';
-import {
- debounceTime,
- distinctUntilChanged,
- switchMap,
- takeUntil,
- take,
-} from 'rxjs/operators';
+import { debounceTime, distinctUntilChanged, switchMap, takeUntil } from 'rxjs/operators';
import { UnsplashService, UnsplashPhoto } from '../../core/unsplash/unsplash.service';
import { GlobalThemeService } from '../../core/theme/global-theme.service';
import { TranslateModule } from '@ngx-translate/core';
@@ -108,13 +102,9 @@ export class DialogUnsplashPickerComponent implements OnInit, OnDestroy {
this.isLoading.set(true);
// If empty query, use context-aware default
if (!query.trim()) {
- return this._globalThemeService.isDarkTheme$.pipe(
- take(1),
- switchMap((isDark) => {
- const defaultQuery = this.getDefaultSearchQuery(isDark);
- return this._unsplashService.searchPhotos(defaultQuery);
- }),
- );
+ const isDark = this._globalThemeService.isDarkTheme();
+ const defaultQuery = this.getDefaultSearchQuery(isDark);
+ return this._unsplashService.searchPhotos(defaultQuery);
}
return this._unsplashService.searchPhotos(query);
}),
@@ -132,9 +122,8 @@ export class DialogUnsplashPickerComponent implements OnInit, OnDestroy {
});
// Initial load with context-aware defaults
- this._globalThemeService.isDarkTheme$.pipe(take(1)).subscribe((isDark) => {
- this.onSearchChange(this.getDefaultSearchQuery(isDark));
- });
+ const isDark = this._globalThemeService.isDarkTheme();
+ this.onSearchChange(this.getDefaultSearchQuery(isDark));
}
ngOnDestroy(): void {
diff --git a/src/app/ui/inline-markdown/inline-markdown.component.html b/src/app/ui/inline-markdown/inline-markdown.component.html
index 6b8ff227d..938081d99 100644
--- a/src/app/ui/inline-markdown/inline-markdown.component.html
+++ b/src/app/ui/inline-markdown/inline-markdown.component.html
@@ -1,9 +1,9 @@
- @if (isShowEdit || isTurnOffMarkdownParsing()) {
+ @if (isShowEdit() || isTurnOffMarkdownParsing()) {
@@ -24,7 +24,7 @@
#previewEl
(click)="clickPreview($event)"
[data]="model"
- [hidden]="isShowEdit"
+ [hidden]="isShowEdit()"
class="mat-body-2 markdown-parsed markdown"
markdown
tabindex="0"
diff --git a/src/app/ui/inline-markdown/inline-markdown.component.ts b/src/app/ui/inline-markdown/inline-markdown.component.ts
index 24e6382fb..069d73a5e 100644
--- a/src/app/ui/inline-markdown/inline-markdown.component.ts
+++ b/src/app/ui/inline-markdown/inline-markdown.component.ts
@@ -11,6 +11,7 @@ import {
OnDestroy,
OnInit,
output,
+ signal,
viewChild,
} from '@angular/core';
import { fadeInAnimation } from '../animations/fade.ani';
@@ -53,10 +54,10 @@ export class InlineMarkdownComponent implements OnInit, OnDestroy {
readonly textareaEl = viewChild('textareaEl');
readonly previewEl = viewChild('previewEl');
- isHideOverflow: boolean = false;
- isChecklistMode: boolean = false;
- isShowEdit: boolean = false;
- modelCopy: string | undefined;
+ isHideOverflow = signal(false);
+ isChecklistMode = signal(false);
+ isShowEdit = signal(false);
+ modelCopy = signal(undefined);
isTurnOffMarkdownParsing = computed(() => {
const misc = this._globalConfigService.misc();
@@ -69,7 +70,7 @@ export class InlineMarkdownComponent implements OnInit, OnDestroy {
}
@HostBinding('class.isFocused') get isFocused(): boolean {
- return this.isShowEdit;
+ return this.isShowEdit();
}
private _model: string | undefined;
@@ -82,25 +83,26 @@ export class InlineMarkdownComponent implements OnInit, OnDestroy {
// Accessor inputs cannot be migrated as they are too complex.
@Input() set model(v: string | undefined) {
this._model = v;
- this.modelCopy = v;
+ this.modelCopy.set(v);
- if (!this.isShowEdit) {
+ if (!this.isShowEdit()) {
window.setTimeout(() => {
this.resizeParsedToFit();
});
}
- this.isChecklistMode =
- this.isChecklistMode &&
- this.isShowChecklistToggle() &&
- !!v &&
- isMarkdownChecklist(v);
+ this.isChecklistMode.set(
+ this.isChecklistMode() &&
+ this.isShowChecklistToggle() &&
+ !!v &&
+ isMarkdownChecklist(v),
+ );
}
// TODO: Skipped for migration because:
// Accessor inputs cannot be migrated as they are too complex.
@Input() set isFocus(val: boolean) {
- if (!this.isShowEdit && val) {
+ if (!this.isShowEdit() && val) {
this._toggleShowEdit();
}
}
@@ -123,7 +125,7 @@ export class InlineMarkdownComponent implements OnInit, OnDestroy {
}
checklistToggle(): void {
- this.isChecklistMode = !this.isChecklistMode;
+ this.isChecklistMode.set(!this.isChecklistMode());
}
keypressHandler(ev: KeyboardEvent): void {
@@ -154,17 +156,17 @@ export class InlineMarkdownComponent implements OnInit, OnDestroy {
untoggleShowEdit(): void {
if (!this.isLock()) {
this.resizeParsedToFit();
- this.isShowEdit = false;
+ this.isShowEdit.set(false);
}
const textareaEl = this.textareaEl();
if (!textareaEl) {
throw new Error('Textarea not visible');
}
- this.modelCopy = textareaEl.nativeElement.value;
+ this.modelCopy.set(textareaEl.nativeElement.value);
- if (this.modelCopy !== this.model) {
- this.model = this.modelCopy;
- this.changed.emit(this.modelCopy as string);
+ if (this.modelCopy() !== this.model) {
+ this.model = this.modelCopy();
+ this.changed.emit(this.modelCopy() as string);
}
}
@@ -190,13 +192,13 @@ export class InlineMarkdownComponent implements OnInit, OnDestroy {
height: '100vh',
restoreFocus: true,
data: {
- content: this.modelCopy,
+ content: this.modelCopy(),
},
})
.afterClosed()
.subscribe((res) => {
if (typeof res === 'string') {
- this.modelCopy = res;
+ this.modelCopy.set(res);
this.changed.emit(res);
}
});
@@ -236,40 +238,44 @@ export class InlineMarkdownComponent implements OnInit, OnDestroy {
toggleChecklistMode(ev: Event): void {
ev.preventDefault();
ev.stopPropagation();
- this.isChecklistMode = true;
+ this.isChecklistMode.set(true);
this._toggleShowEdit();
if (this.isDefaultText()) {
- this.modelCopy = '- [ ] ';
+ this.modelCopy.set('- [ ] ');
} else {
- this.modelCopy += '\n- [ ] ';
+ this.modelCopy.set(this.modelCopy() + '\n- [ ] ');
// cleanup string on add
- this.modelCopy = this.modelCopy?.replace(/\n\n- \[/g, '\n- [').replace(/^\n/g, '');
+ this.modelCopy.set(
+ this.modelCopy()
+ ?.replace(/\n\n- \[/g, '\n- [')
+ .replace(/^\n/g, ''),
+ );
}
}
private _toggleShowEdit(): void {
- this.isShowEdit = true;
- this.modelCopy = this.model || '';
+ this.isShowEdit.set(true);
+ this.modelCopy.set(this.model || '');
setTimeout(() => {
const textareaEl = this.textareaEl();
if (!textareaEl) {
throw new Error('Textarea not visible');
}
- textareaEl.nativeElement.value = this.modelCopy;
+ textareaEl.nativeElement.value = this.modelCopy();
textareaEl.nativeElement.focus();
this.resizeTextareaToFit();
});
}
private _hideOverflow(): void {
- this.isHideOverflow = true;
+ this.isHideOverflow.set(true);
if (this._hideOverFlowTimeout) {
window.clearTimeout(this._hideOverFlowTimeout);
}
this._hideOverFlowTimeout = window.setTimeout(() => {
- this.isHideOverflow = false;
+ this.isHideOverflow.set(false);
this._cd.detectChanges();
}, HIDE_OVERFLOW_TIMEOUT_DURATION);
}
@@ -311,12 +317,12 @@ export class InlineMarkdownComponent implements OnInit, OnDestroy {
allLines[itemIndex] = item.includes('[ ]')
? item.replace('[ ]', '[x]').replace('[]', '[x]')
: item.replace('[x]', '[ ]');
- this.modelCopy = allLines.join('\n');
+ this.modelCopy.set(allLines.join('\n'));
// Update the markdown string
- if (this.modelCopy !== this.model) {
- this.model = this.modelCopy;
- this.changed.emit(this.modelCopy);
+ if (this.modelCopy() !== this.model) {
+ this.model = this.modelCopy();
+ this.changed.emit(this.modelCopy() as string);
}
}
}