mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-04-02 05:23:14 +00:00
feat(portal): add scrolling to the desktop (#2410)
* feat(portal): add scrolling to the desktop * chore: comments * chore: fix
This commit is contained in:
@@ -13,10 +13,10 @@ import { MonacoEditorModule } from '@materia-ui/ngx-monaco-editor'
|
||||
import {
|
||||
MarkdownModule,
|
||||
DarkThemeModule,
|
||||
ResponsiveColModule,
|
||||
SharedPipesModule,
|
||||
LightThemeModule,
|
||||
LoadingModule,
|
||||
ResponsiveColViewportDirective,
|
||||
} from '@start9labs/shared'
|
||||
|
||||
import { AppComponent } from './app.component'
|
||||
@@ -61,7 +61,7 @@ import { environment } from '../environments/environment'
|
||||
TuiModeModule,
|
||||
TuiThemeNightModule,
|
||||
WidgetsPageModule,
|
||||
ResponsiveColModule,
|
||||
ResponsiveColViewportDirective,
|
||||
DarkThemeModule,
|
||||
LightThemeModule,
|
||||
ServiceWorkerModule.register('ngsw-worker.js', {
|
||||
|
||||
@@ -61,4 +61,9 @@ export class CardComponent {
|
||||
|
||||
this.navigation.addTab({ icon, title, routerLink })
|
||||
}
|
||||
|
||||
@HostListener('pointerdown.prevent')
|
||||
onDown() {
|
||||
// Prevents Firefox from starting a native drag
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
import { tuiGetActualTarget, tuiIsElement, tuiPx } from '@taiga-ui/cdk'
|
||||
import { DrawerComponent } from './drawer.component'
|
||||
import { DesktopService } from '../../services/desktop.service'
|
||||
import { TuiAlertService } from '@taiga-ui/core'
|
||||
|
||||
/**
|
||||
* This directive is responsible for drag and drop of the drawer item.
|
||||
@@ -17,10 +18,12 @@ import { DesktopService } from '../../services/desktop.service'
|
||||
selector: '[drawerItem]',
|
||||
standalone: true,
|
||||
host: {
|
||||
'[style.userSelect]': '"none"',
|
||||
'[style.touchAction]': '"none"',
|
||||
},
|
||||
})
|
||||
export class DrawerItemDirective {
|
||||
private readonly alerts = inject(TuiAlertService)
|
||||
private readonly desktop = inject(DesktopService)
|
||||
private readonly drawer = inject(DrawerComponent)
|
||||
private readonly element: HTMLElement = inject(ElementRef).nativeElement
|
||||
@@ -31,11 +34,8 @@ export class DrawerItemDirective {
|
||||
@Input()
|
||||
drawerItem = ''
|
||||
|
||||
@HostListener('pointerdown.prevent.silent', ['$event'])
|
||||
@HostListener('pointerdown.silent', ['$event'])
|
||||
onStart(event: PointerEvent): void {
|
||||
// This element is already on the desktop
|
||||
if (this.desktop.items.includes(this.drawerItem)) return
|
||||
|
||||
const target = tuiGetActualTarget(event)
|
||||
const { x, y, pointerId } = event
|
||||
const { left, top } = this.element.getBoundingClientRect()
|
||||
@@ -62,6 +62,15 @@ export class DrawerItemDirective {
|
||||
onMove(x: number, y: number): void {
|
||||
// This element is not dragged
|
||||
if (Number.isNaN(this.x)) return
|
||||
// This element is already on the desktop
|
||||
if (this.desktop.items.includes(this.drawerItem)) {
|
||||
this.onPointer()
|
||||
this.alerts
|
||||
.open('This item is already added', { status: 'warning' })
|
||||
.subscribe()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
this.process(x, y)
|
||||
this.desktop.add('')
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
</button>
|
||||
</tui-opt-group>
|
||||
<tui-opt-group>
|
||||
<button tuiOption class="item" (click)="({})">
|
||||
<button tuiOption class="item" (click)="logout()">
|
||||
<tui-svg src="tuiIconLogOut"></tui-svg>
|
||||
Logout
|
||||
</button>
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core'
|
||||
import { ChangeDetectionStrategy, Component, inject } from '@angular/core'
|
||||
import {
|
||||
TuiButtonModule,
|
||||
TuiDataListModule,
|
||||
TuiHostedDropdownModule,
|
||||
TuiSvgModule,
|
||||
} from '@taiga-ui/core'
|
||||
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
||||
import { AuthService } from 'src/app/services/auth.service'
|
||||
|
||||
@Component({
|
||||
selector: 'header-menu',
|
||||
@@ -19,4 +21,12 @@ import {
|
||||
TuiButtonModule,
|
||||
],
|
||||
})
|
||||
export class HeaderMenuComponent {}
|
||||
export class HeaderMenuComponent {
|
||||
private readonly api = inject(ApiService)
|
||||
private readonly auth = inject(AuthService)
|
||||
|
||||
logout() {
|
||||
this.api.logout({}).catch(e => console.error('Failed to log out', e))
|
||||
this.auth.setUnverified()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,8 +27,8 @@ export class ToDesktopItemPipe implements PipeTransform {
|
||||
}
|
||||
|
||||
return {
|
||||
icon: packages[id].icon,
|
||||
title: packages[id].manifest.title,
|
||||
icon: packages[id]?.icon,
|
||||
title: packages[id]?.manifest.title,
|
||||
routerLink,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,30 +12,32 @@
|
||||
@tuiScaleIn
|
||||
(pointerup)="onRemove()"
|
||||
></tui-svg>
|
||||
<tui-tiles
|
||||
*ngIf="packages$ | async as packages"
|
||||
class="tiles"
|
||||
@tuiParentStop
|
||||
[debounce]="500"
|
||||
[order]="desktop.order"
|
||||
(orderChange)="onReorder($event)"
|
||||
>
|
||||
<tui-tile
|
||||
*ngFor="let item of desktop.items; let index = index"
|
||||
class="item"
|
||||
[style.order]="desktop.order.get(index)"
|
||||
[desktopItem]="item"
|
||||
<div dragScroller tuiFade="vertical" class="fade">
|
||||
<tui-tiles
|
||||
*ngIf="packages$ | async as packages"
|
||||
class="tiles"
|
||||
@tuiParentStop
|
||||
[debounce]="500"
|
||||
[order]="desktop.order"
|
||||
(orderChange)="onReorder($event)"
|
||||
>
|
||||
<a
|
||||
*ngIf="packages | toDesktopItem : item as desktopItem"
|
||||
tuiTileHandle
|
||||
appCard
|
||||
@tuiFadeIn
|
||||
[id]="item"
|
||||
[title]="desktopItem.title"
|
||||
[icon]="desktopItem.icon"
|
||||
[routerLink]="desktopItem.routerLink"
|
||||
></a>
|
||||
</tui-tile>
|
||||
</tui-tiles>
|
||||
<tui-tile
|
||||
*ngFor="let item of desktop.items; let index = index"
|
||||
class="item"
|
||||
[style.order]="desktop.order.get(index)"
|
||||
[desktopItem]="item"
|
||||
>
|
||||
<a
|
||||
*ngIf="packages | toDesktopItem : item as desktopItem"
|
||||
tuiTileHandle
|
||||
appCard
|
||||
@tuiFadeIn
|
||||
[id]="item"
|
||||
[title]="desktopItem.title"
|
||||
[icon]="desktopItem.icon"
|
||||
[routerLink]="desktopItem.routerLink"
|
||||
></a>
|
||||
</tui-tile>
|
||||
</tui-tiles>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
@@ -6,9 +6,8 @@
|
||||
align-content: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
max-width: 56rem;
|
||||
max-width: calc(100vw - 4rem);
|
||||
margin: 0 auto;
|
||||
padding: 1rem 0;
|
||||
}
|
||||
|
||||
.loader {
|
||||
@@ -16,13 +15,30 @@
|
||||
width: 10rem;
|
||||
}
|
||||
|
||||
.fade {
|
||||
@include scrollbar-hidden();
|
||||
|
||||
width: 100%;
|
||||
height: calc(100% - 4rem);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.tiles {
|
||||
width: 100%;
|
||||
min-height: 5.5rem;
|
||||
justify-content: center;
|
||||
grid-template-columns: repeat(auto-fit, 12.5rem);
|
||||
grid-auto-rows: 5.5rem;
|
||||
grid-auto-rows: min-content;
|
||||
gap: 2rem;
|
||||
margin: auto;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
grid-column: 1;
|
||||
height: 1rem;
|
||||
order: 999;
|
||||
}
|
||||
}
|
||||
|
||||
.remove {
|
||||
@@ -41,8 +57,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
.item._dragged,
|
||||
.item._empty {
|
||||
border-radius: var(--tui-radius-l);
|
||||
box-shadow: inset 0 0 0 0.5rem var(--tui-clear-active);
|
||||
.item {
|
||||
height: 5.5rem;
|
||||
|
||||
&._dragged,
|
||||
&._empty {
|
||||
border-radius: var(--tui-radius-l);
|
||||
box-shadow: inset 0 0 0 0.5rem var(--tui-clear-active);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { CommonModule } from '@angular/common'
|
||||
import { NgModule } from '@angular/core'
|
||||
import { RouterModule, Routes } from '@angular/router'
|
||||
import { DragScrollerDirective } from '@start9labs/shared'
|
||||
import { TuiLoaderModule, TuiSvgModule } from '@taiga-ui/core'
|
||||
import { TuiFadeModule } from '@taiga-ui/experimental'
|
||||
import { TuiTilesModule } from '@taiga-ui/kit'
|
||||
import { DesktopComponent } from './desktop.component'
|
||||
import { CardComponent } from '../../components/card/card.component'
|
||||
@@ -25,6 +27,8 @@ const ROUTES: Routes = [
|
||||
TuiTilesModule,
|
||||
ToDesktopItemPipe,
|
||||
RouterModule.forChild(ROUTES),
|
||||
TuiFadeModule,
|
||||
DragScrollerDirective,
|
||||
],
|
||||
declarations: [DesktopComponent],
|
||||
exports: [DesktopComponent],
|
||||
|
||||
@@ -6,7 +6,7 @@ import { IonicModule } from '@ionic/angular'
|
||||
import {
|
||||
SharedPipesModule,
|
||||
EmverPipesModule,
|
||||
ResponsiveColModule,
|
||||
ResponsiveColDirective,
|
||||
} from '@start9labs/shared'
|
||||
import {
|
||||
FilterPackagesPipeModule,
|
||||
@@ -45,7 +45,7 @@ const routes: Routes = [
|
||||
SkeletonModule,
|
||||
MarketplaceSettingsPageModule,
|
||||
StoreIconComponentModule,
|
||||
ResponsiveColModule,
|
||||
ResponsiveColDirective,
|
||||
],
|
||||
declarations: [MarketplaceListPage],
|
||||
exports: [MarketplaceListPage],
|
||||
|
||||
@@ -5,7 +5,7 @@ import { IonicModule } from '@ionic/angular'
|
||||
import { AppListPage } from './app-list.page'
|
||||
import {
|
||||
EmverPipesModule,
|
||||
ResponsiveColModule,
|
||||
ResponsiveColDirective,
|
||||
TextSpinnerComponentModule,
|
||||
TickerModule,
|
||||
} from '@start9labs/shared'
|
||||
@@ -35,7 +35,7 @@ const routes: Routes = [
|
||||
RouterModule.forChild(routes),
|
||||
BadgeMenuComponentModule,
|
||||
WidgetListComponentModule,
|
||||
ResponsiveColModule,
|
||||
ResponsiveColDirective,
|
||||
TickerModule,
|
||||
LaunchMenuComponentModule,
|
||||
],
|
||||
|
||||
@@ -5,7 +5,7 @@ import { IonicModule } from '@ionic/angular'
|
||||
import { AppShowPage } from './app-show.page'
|
||||
import {
|
||||
EmverPipesModule,
|
||||
ResponsiveColModule,
|
||||
ResponsiveColDirective,
|
||||
SharedPipesModule,
|
||||
} from '@start9labs/shared'
|
||||
import { StatusComponentModule } from '../status/status.component.module'
|
||||
@@ -59,7 +59,7 @@ const routes: Routes = [
|
||||
RouterModule.forChild(routes),
|
||||
AppConfigPageModule,
|
||||
EmverPipesModule,
|
||||
ResponsiveColModule,
|
||||
ResponsiveColDirective,
|
||||
SharedPipesModule,
|
||||
InsecureWarningComponentModule,
|
||||
LaunchMenuComponentModule,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { NgModule } from '@angular/core'
|
||||
import { CommonModule } from '@angular/common'
|
||||
import { MarkdownPipeModule, SafeLinksModule } from '@start9labs/shared'
|
||||
import { MarkdownPipeModule, SafeLinksDirective } from '@start9labs/shared'
|
||||
import { TuiButtonModule, TuiScrollbarModule } from '@taiga-ui/core'
|
||||
import { TuiAutoFocusModule } from '@taiga-ui/cdk'
|
||||
import { NgDompurifyModule } from '@tinkoff/ng-dompurify'
|
||||
@@ -14,7 +14,7 @@ import { OSUpdatePage } from './os-update.page'
|
||||
TuiButtonModule,
|
||||
TuiAutoFocusModule,
|
||||
TuiScrollbarModule,
|
||||
SafeLinksModule,
|
||||
SafeLinksDirective,
|
||||
NgDompurifyModule,
|
||||
],
|
||||
exports: [OSUpdatePage],
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
import {
|
||||
EmverPipesModule,
|
||||
MarkdownPipeModule,
|
||||
SafeLinksModule,
|
||||
SafeLinksDirective,
|
||||
SharedPipesModule,
|
||||
} from '@start9labs/shared'
|
||||
import { NgDompurifyModule } from '@tinkoff/ng-dompurify'
|
||||
@@ -40,7 +40,7 @@ const routes: Routes = [
|
||||
StoreIconComponentModule,
|
||||
EmverPipesModule,
|
||||
MimeTypePipeModule,
|
||||
SafeLinksModule,
|
||||
SafeLinksDirective,
|
||||
NgDompurifyModule,
|
||||
TuiProgressModule,
|
||||
],
|
||||
|
||||
@@ -2,14 +2,14 @@ import { NgModule } from '@angular/core'
|
||||
import { CommonModule } from '@angular/common'
|
||||
import { IonicModule } from '@ionic/angular'
|
||||
import { RouterModule } from '@angular/router'
|
||||
import { ResponsiveColModule } from '@start9labs/shared'
|
||||
import { ResponsiveColDirective } from '@start9labs/shared'
|
||||
import { AnyLinkComponent } from './any-link/any-link.component'
|
||||
import { WidgetListComponent } from './widget-list.component'
|
||||
import { WidgetCardComponent } from './widget-card/widget-card.component'
|
||||
|
||||
@NgModule({
|
||||
declarations: [WidgetListComponent, WidgetCardComponent, AnyLinkComponent],
|
||||
imports: [CommonModule, IonicModule, RouterModule, ResponsiveColModule],
|
||||
imports: [CommonModule, IonicModule, RouterModule, ResponsiveColDirective],
|
||||
exports: [WidgetListComponent],
|
||||
})
|
||||
export class WidgetListComponentModule {}
|
||||
|
||||
Reference in New Issue
Block a user