mirror of
https://github.com/johannesjo/super-productivity.git
synced 2026-07-28 18:20:42 +00:00
refactor: migrate side panel over mode logic to signals
- Move isCustomOver logic from right-panel component to layout service - Implement using signals and computed properties for better performance - Add isRightPanelOverCustom computed signal in layout service - Maintain behavior: work-view routes use responsive mode, non-work-view routes force over mode unless on very big screens (≥1270px) - Update right-panel component to use the new signal-based API
This commit is contained in:
parent
b99a1654cb
commit
22fce24bca
3 changed files with 59 additions and 5 deletions
|
|
@ -1,4 +1,4 @@
|
|||
import { inject, Injectable } from '@angular/core';
|
||||
import { inject, Injectable, computed } from '@angular/core';
|
||||
import {
|
||||
hideAddTaskBar,
|
||||
hideIssuePanel,
|
||||
|
|
@ -22,16 +22,18 @@ import {
|
|||
selectIsShowSideNav,
|
||||
selectIsShowTaskViewCustomizerPanel,
|
||||
} from './store/layout.reducer';
|
||||
import { filter, map, switchMap, withLatestFrom } from 'rxjs/operators';
|
||||
import { filter, map, switchMap, withLatestFrom, startWith } from 'rxjs/operators';
|
||||
import { BreakpointObserver } from '@angular/cdk/layout';
|
||||
import { NavigationStart, Router } from '@angular/router';
|
||||
import { NavigationStart, NavigationEnd, Router } from '@angular/router';
|
||||
import { WorkContextService } from '../../features/work-context/work-context.service';
|
||||
import { selectMiscConfig } from '../../features/config/store/global-config.reducer';
|
||||
import { toSignal } from '@angular/core/rxjs-interop';
|
||||
|
||||
const NAV_ALWAYS_VISIBLE = 1200;
|
||||
const NAV_OVER_RIGHT_PANEL_NEXT = 800;
|
||||
const BOTH_OVER = 720;
|
||||
const XS_MAX = 599;
|
||||
const VERY_BIG_SCREEN = 1270;
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
|
|
@ -62,6 +64,46 @@ export class LayoutService {
|
|||
isRightPanelOver$: Observable<boolean> = this._breakPointObserver
|
||||
.observe([`(min-width: ${BOTH_OVER}px)`])
|
||||
.pipe(map((result) => !result.matches));
|
||||
|
||||
// Signals for custom right panel behavior
|
||||
private readonly _isVeryBigScreen = toSignal(
|
||||
this._breakPointObserver
|
||||
.observe([`(min-width: ${VERY_BIG_SCREEN}px)`])
|
||||
.pipe(map((result) => result.matches)),
|
||||
{ initialValue: false },
|
||||
);
|
||||
|
||||
private readonly _isWorkViewRoute = toSignal(
|
||||
this._router.events.pipe(
|
||||
filter((event): event is NavigationEnd => event instanceof NavigationEnd),
|
||||
map((event) => this._isWorkViewUrl(event.urlAfterRedirects)),
|
||||
startWith(this._isWorkViewUrl(this._router.url)),
|
||||
),
|
||||
{ initialValue: this._isWorkViewUrl(this._router.url) },
|
||||
);
|
||||
|
||||
private readonly _isRightPanelOverDefault = toSignal(this.isRightPanelOver$, {
|
||||
initialValue: false,
|
||||
});
|
||||
|
||||
// Computed signal for custom right panel over behavior
|
||||
readonly isRightPanelOverCustom = computed(() => {
|
||||
const isWorkView = this._isWorkViewRoute();
|
||||
const isVeryBigScreen = this._isVeryBigScreen();
|
||||
const defaultIsOver = this._isRightPanelOverDefault();
|
||||
|
||||
// Use default behavior if on work view
|
||||
if (isWorkView) {
|
||||
return defaultIsOver;
|
||||
}
|
||||
|
||||
// For non-work-view routes: use "over" mode unless on very big screen
|
||||
return !isVeryBigScreen;
|
||||
});
|
||||
|
||||
private _isWorkViewUrl(url: string): boolean {
|
||||
return url.includes('/active/') || url.includes('/tag/') || url.includes('/project/');
|
||||
}
|
||||
isNavOver$: Observable<boolean> = this._store$.select(selectMiscConfig).pipe(
|
||||
switchMap((miscCfg) => {
|
||||
if (miscCfg.isUseMinimalNav) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<better-drawer-container
|
||||
(wasClosed)="close()"
|
||||
[isOpen]="isOpen$ | async"
|
||||
[isOver]="isAlwaysOver() || (layoutService.isRightPanelOver$ | async)"
|
||||
[isOver]="isCustomOver()"
|
||||
[sideWidth]="40"
|
||||
>
|
||||
<ng-container better-drawer-content>
|
||||
|
|
@ -25,7 +25,7 @@
|
|||
} @else if (selectedTaskWithDelayForNone$ | async) {
|
||||
@let selectedTaskWithDelayForNone = selectedTaskWithDelayForNone$ | async;
|
||||
<task-detail-panel
|
||||
[isOver]="isAlwaysOver() || (layoutService.isRightPanelOver$ | async)"
|
||||
[isOver]="isCustomOver()"
|
||||
[@taskDetailPanelTaskChange]="selectedTaskWithDelayForNone?.id"
|
||||
[@.disabled]="isDisableTaskPanelAni"
|
||||
[task]="selectedTaskWithDelayForNone"
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import {
|
|||
inject,
|
||||
input,
|
||||
OnDestroy,
|
||||
computed,
|
||||
} from '@angular/core';
|
||||
import { combineLatest, Observable, of, Subscription } from 'rxjs';
|
||||
import { TaskDetailTargetPanel, TaskWithSubTasks } from '../tasks/task.model';
|
||||
|
|
@ -69,6 +70,17 @@ export class RightPanelComponent implements OnDestroy {
|
|||
// NOTE: used for debugging
|
||||
readonly isAlwaysOver = input<boolean>(false);
|
||||
|
||||
// Use the computed signal from layout service
|
||||
readonly isCustomOver = computed(() => {
|
||||
// Always use "over" mode for debugging
|
||||
if (this.isAlwaysOver()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Use the layout service's computed signal
|
||||
return this.layoutService.isRightPanelOverCustom();
|
||||
});
|
||||
|
||||
// to still display its data when panel is closing
|
||||
selectedTaskWithDelayForNone$: Observable<TaskWithSubTasks | null> =
|
||||
this.taskService.selectedTask$.pipe(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue