mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-04-04 14:29:45 +00:00
highlight instructions if not viewed (#1731)
This commit is contained in:
@@ -158,6 +158,10 @@ export class AppActionsPage {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await this.embassyApi.uninstallPackage({ id: this.pkgId })
|
await this.embassyApi.uninstallPackage({ id: this.pkgId })
|
||||||
|
this.embassyApi.setDbValue({
|
||||||
|
pointer: `/ack-instructions/${this.pkgId}`,
|
||||||
|
value: false,
|
||||||
|
})
|
||||||
this.navCtrl.navigateRoot('/services')
|
this.navCtrl.navigateRoot('/services')
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
this.errToast.present(e)
|
this.errToast.present(e)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { Component } from '@angular/core'
|
|||||||
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
|
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
|
||||||
import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
|
import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
|
||||||
import { Observable } from 'rxjs'
|
import { Observable } from 'rxjs'
|
||||||
import { filter, map, switchMapTo, take, takeUntil, tap } from 'rxjs/operators'
|
import { filter, map, switchMap, take, takeUntil, tap } from 'rxjs/operators'
|
||||||
import { isEmptyObject, exists, DestroyService } from '@start9labs/shared'
|
import { isEmptyObject, exists, DestroyService } from '@start9labs/shared'
|
||||||
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
||||||
import { parseDataModel, RecoveredInfo } from 'src/app/util/parse-data-model'
|
import { parseDataModel, RecoveredInfo } from 'src/app/util/parse-data-model'
|
||||||
@@ -16,7 +16,6 @@ import { parseDataModel, RecoveredInfo } from 'src/app/util/parse-data-model'
|
|||||||
export class AppListPage {
|
export class AppListPage {
|
||||||
pkgs: readonly PackageDataEntry[] = []
|
pkgs: readonly PackageDataEntry[] = []
|
||||||
recoveredPkgs: readonly RecoveredInfo[] = []
|
recoveredPkgs: readonly RecoveredInfo[] = []
|
||||||
order: readonly string[] = []
|
|
||||||
reordering = false
|
reordering = false
|
||||||
|
|
||||||
readonly connected$ = this.patch.connected$
|
readonly connected$ = this.patch.connected$
|
||||||
@@ -38,17 +37,11 @@ export class AppListPage {
|
|||||||
filter(data => exists(data) && !isEmptyObject(data)),
|
filter(data => exists(data) && !isEmptyObject(data)),
|
||||||
take(1),
|
take(1),
|
||||||
map(parseDataModel),
|
map(parseDataModel),
|
||||||
tap(({ order, pkgs, recoveredPkgs }) => {
|
tap(({ pkgs, recoveredPkgs }) => {
|
||||||
this.pkgs = pkgs
|
this.pkgs = pkgs
|
||||||
this.recoveredPkgs = recoveredPkgs
|
this.recoveredPkgs = recoveredPkgs
|
||||||
this.order = order
|
|
||||||
|
|
||||||
// set order in UI DB if there were unknown packages
|
|
||||||
if (order.length < pkgs.length) {
|
|
||||||
this.setOrder()
|
|
||||||
}
|
|
||||||
}),
|
}),
|
||||||
switchMapTo(this.watchNewlyRecovered()),
|
switchMap(() => this.watchNewlyRecovered()),
|
||||||
takeUntil(this.destroy$),
|
takeUntil(this.destroy$),
|
||||||
)
|
)
|
||||||
.subscribe()
|
.subscribe()
|
||||||
@@ -88,7 +81,7 @@ export class AppListPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private setOrder(): void {
|
private setOrder(): void {
|
||||||
this.order = this.pkgs.map(pkg => pkg.manifest.id)
|
const order = this.pkgs.map(pkg => pkg.manifest.id)
|
||||||
this.api.setDbValue({ pointer: '/pkg-order', value: this.order })
|
this.api.setDbValue({ pointer: '/pkg-order', value: order })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
detail
|
detail
|
||||||
(click)="button.action()"
|
(click)="button.action()"
|
||||||
[disabled]="button.disabled"
|
[disabled]="button.disabled"
|
||||||
|
[ngClass]="{ highlighted: button.highlighted$ | async }"
|
||||||
>
|
>
|
||||||
<ion-icon slot="start" [name]="button.icon"></ion-icon>
|
<ion-icon slot="start" [name]="button.icon"></ion-icon>
|
||||||
<ion-label>
|
<ion-label>
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
.highlighted {
|
||||||
|
* {
|
||||||
|
color: var(--ion-color-dark);
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ import { Button } from '../../pipes/to-buttons.pipe'
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'app-show-menu',
|
selector: 'app-show-menu',
|
||||||
templateUrl: './app-show-menu.component.html',
|
templateUrl: './app-show-menu.component.html',
|
||||||
|
styleUrls: ['./app-show-menu.component.scss'],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
})
|
})
|
||||||
export class AppShowMenuComponent {
|
export class AppShowMenuComponent {
|
||||||
|
|||||||
@@ -13,14 +13,16 @@ import {
|
|||||||
} from 'src/app/services/patch-db/data-model'
|
} from 'src/app/services/patch-db/data-model'
|
||||||
import { ModalService } from 'src/app/services/modal.service'
|
import { ModalService } from 'src/app/services/modal.service'
|
||||||
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
||||||
import { from } from 'rxjs'
|
import { from, map, Observable } from 'rxjs'
|
||||||
import { Marketplace } from '@start9labs/marketplace'
|
import { Marketplace } from '@start9labs/marketplace'
|
||||||
import { ActionMarketplaceComponent } from 'src/app/modals/action-marketplace/action-marketplace.component'
|
import { ActionMarketplaceComponent } from 'src/app/modals/action-marketplace/action-marketplace.component'
|
||||||
|
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
|
||||||
export interface Button {
|
export interface Button {
|
||||||
title: string
|
title: string
|
||||||
description: string
|
description: string
|
||||||
icon: string
|
icon: string
|
||||||
action: Function
|
action: Function
|
||||||
|
highlighted$?: Observable<boolean>
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,6 +38,7 @@ export class ToButtonsPipe implements PipeTransform {
|
|||||||
private readonly modalCtrl: ModalController,
|
private readonly modalCtrl: ModalController,
|
||||||
private readonly modalService: ModalService,
|
private readonly modalService: ModalService,
|
||||||
private readonly apiService: ApiService,
|
private readonly apiService: ApiService,
|
||||||
|
private readonly patch: PatchDbService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
transform(
|
transform(
|
||||||
@@ -52,6 +55,9 @@ export class ToButtonsPipe implements PipeTransform {
|
|||||||
title: 'Instructions',
|
title: 'Instructions',
|
||||||
description: `Understand how to use ${pkgTitle}`,
|
description: `Understand how to use ${pkgTitle}`,
|
||||||
icon: 'list-outline',
|
icon: 'list-outline',
|
||||||
|
highlighted$: this.patch
|
||||||
|
.watch$('ui', 'ack-instructions', pkg.manifest.id)
|
||||||
|
.pipe(map(seen => !seen)),
|
||||||
},
|
},
|
||||||
// config
|
// config
|
||||||
{
|
{
|
||||||
@@ -111,6 +117,11 @@ export class ToButtonsPipe implements PipeTransform {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async presentModalInstructions(pkg: PackageDataEntry) {
|
private async presentModalInstructions(pkg: PackageDataEntry) {
|
||||||
|
this.apiService.setDbValue({
|
||||||
|
pointer: `/ack-instructions/${pkg.manifest.id}`,
|
||||||
|
value: true,
|
||||||
|
})
|
||||||
|
|
||||||
const modal = await this.modalCtrl.create({
|
const modal = await this.modalCtrl.create({
|
||||||
componentProps: {
|
componentProps: {
|
||||||
title: 'Instructions',
|
title: 'Instructions',
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ export const mockPatchData: DataModel = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
'ack-instructions': {},
|
||||||
},
|
},
|
||||||
'server-info': {
|
'server-info': {
|
||||||
id: 'abcdefgh',
|
id: 'abcdefgh',
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ export interface UIData {
|
|||||||
'high-score': number
|
'high-score': number
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
'ack-instructions': Record<string, boolean>
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UIMarketplaceData {
|
export interface UIMarketplaceData {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { first } from 'rxjs/operators'
|
|
||||||
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
|
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
|
||||||
import { ServerInfo } from 'src/app/services/patch-db/data-model'
|
import { ServerInfo } from 'src/app/services/patch-db/data-model'
|
||||||
import { firstValueFrom } from 'rxjs'
|
import { firstValueFrom } from 'rxjs'
|
||||||
|
|||||||
@@ -9,8 +9,7 @@ export function parseDataModel(data: DataModel): ParsedData {
|
|||||||
JSON.stringify(data['package-data']),
|
JSON.stringify(data['package-data']),
|
||||||
)
|
)
|
||||||
|
|
||||||
const order = [...(data.ui['pkg-order'] || [])]
|
// recovered packages (0.2.x)
|
||||||
const pkgs: PackageDataEntry[] = []
|
|
||||||
const recoveredPkgs = Object.entries(data['recovered-packages'])
|
const recoveredPkgs = Object.entries(data['recovered-packages'])
|
||||||
.filter(([id, _]) => !all[id])
|
.filter(([id, _]) => !all[id])
|
||||||
.map(([id, val]) => ({
|
.map(([id, val]) => ({
|
||||||
@@ -18,6 +17,9 @@ export function parseDataModel(data: DataModel): ParsedData {
|
|||||||
id,
|
id,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
// installed packages
|
||||||
|
const order = [...(data.ui['pkg-order'] || [])]
|
||||||
|
const pkgs: PackageDataEntry[] = []
|
||||||
// add known packages in preferential order
|
// add known packages in preferential order
|
||||||
order.forEach(id => {
|
order.forEach(id => {
|
||||||
if (all[id]) {
|
if (all[id]) {
|
||||||
@@ -33,7 +35,6 @@ export function parseDataModel(data: DataModel): ParsedData {
|
|||||||
})
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
order,
|
|
||||||
pkgs,
|
pkgs,
|
||||||
recoveredPkgs,
|
recoveredPkgs,
|
||||||
}
|
}
|
||||||
@@ -44,7 +45,6 @@ export interface RecoveredInfo extends RecoveredPackageDataEntry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface ParsedData {
|
interface ParsedData {
|
||||||
order: string[]
|
|
||||||
pkgs: PackageDataEntry[]
|
pkgs: PackageDataEntry[]
|
||||||
recoveredPkgs: RecoveredInfo[]
|
recoveredPkgs: RecoveredInfo[]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user