use notification system for OS updates (#2670)

* use notification system for OS updates

* feat: Include the version update notification in the update in rs

* chore: Change the location of the comment

* progress on release notes

* fill out missing sections

* fix build

* fix build

---------

Co-authored-by: J H <dragondef@gmail.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
This commit is contained in:
Matt Hill
2024-12-02 13:58:09 -07:00
committed by GitHub
parent dd423f2e7b
commit 22a32af750
18 changed files with 167 additions and 137 deletions

View File

@@ -22,7 +22,6 @@ import {
import { AppComponent } from './app.component'
import { AppRoutingModule } from './app-routing.module'
import { OSWelcomePageModule } from './modals/os-welcome/os-welcome.module'
import { MarketplaceModule } from './marketplace.module'
import { PreloaderModule } from './app/preloader/preloader.module'
import { FooterModule } from './app/footer/footer.module'
@@ -47,7 +46,6 @@ import { environment } from '../environments/environment'
PreloaderModule,
FooterModule,
EnterModule,
OSWelcomePageModule,
MarkdownModule,
LoadingModule,
MonacoEditorModule,

View File

@@ -2,7 +2,10 @@ import { inject } from '@angular/core'
import { FormControlComponent } from './form-control/form-control.component'
import { IST } from '@start9labs/start-sdk'
export abstract class Control<Spec extends Exclude<IST.ValueSpec, IST.ValueSpecHidden>, Value> {
export abstract class Control<
Spec extends Exclude<IST.ValueSpec, IST.ValueSpecHidden>,
Value,
> {
private readonly control: FormControlComponent<Spec, Value> =
inject(FormControlComponent)

View File

@@ -36,4 +36,4 @@
Accept
</button>
</div>
</ng-template>
</ng-template>

View File

@@ -12,7 +12,12 @@ export const FORM_CONTROL_PROVIDERS: Provider[] = [
{
provide: TUI_VALIDATION_ERRORS,
deps: [forwardRef(() => FormControlComponent)],
useFactory: (control: FormControlComponent<Exclude<IST.ValueSpec, IST.ValueSpecHidden>, string>) => ({
useFactory: (
control: FormControlComponent<
Exclude<IST.ValueSpec, IST.ValueSpecHidden>,
string
>,
) => ({
required: 'Required',
pattern: ({ requiredPattern }: ValidatorsPatternError) =>
('patterns' in control.spec &&

View File

@@ -1,13 +0,0 @@
import { NgModule } from '@angular/core'
import { CommonModule } from '@angular/common'
import { IonicModule } from '@ionic/angular'
import { OSWelcomePage } from './os-welcome.page'
import { SharedPipesModule } from '@start9labs/shared'
import { FormsModule } from '@angular/forms'
@NgModule({
declarations: [OSWelcomePage],
imports: [CommonModule, IonicModule, FormsModule, SharedPipesModule],
exports: [OSWelcomePage],
})
export class OSWelcomePageModule {}

View File

@@ -1,32 +0,0 @@
<ion-header>
<ion-toolbar>
<ion-title>Release Notes</ion-title>
<ion-buttons slot="end">
<ion-button (click)="dismiss()">
<ion-icon slot="icon-only" name="close"></ion-icon>
</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<h2>This Release</h2>
<h4>0.3.6-alpha.8</h4>
<h6>This is an ALPHA release! DO NOT use for production data!</h6>
<h6>
Expect that any data you create or store on this version of the OS can be
LOST FOREVER!
</h6>
<div class="ion-text-center ion-padding">
<ion-button
fill="solid"
color="primary"
(click)="dismiss()"
class="enter-click btn-128"
>
Begin
</ion-button>
</div>
</ion-content>

View File

@@ -1,29 +0,0 @@
.close-button {
width: 100%;
display: flex;
justify-content: center;
align-items: center;
min-height: 100px;
}
.main-content {
color: var(--ion-color-dark);
}
.spaced-list {
li {
padding-bottom: 12px;
}
}
.note-padding {
padding-bottom: 12px;
}
h2 {
font-weight: bold;
}
h4 {
font-style: italic;
}

View File

@@ -1,15 +0,0 @@
import { Component, Input } from '@angular/core'
import { ModalController } from '@ionic/angular'
@Component({
selector: 'os-welcome',
templateUrl: './os-welcome.page.html',
styleUrls: ['./os-welcome.page.scss'],
})
export class OSWelcomePage {
constructor(private readonly modalCtrl: ModalController) {}
async dismiss() {
return this.modalCtrl.dismiss()
}
}

View File

@@ -115,6 +115,15 @@
>
View Report
</ion-button>
<ion-button
*ngIf="not.code === 2"
slot="end"
fill="clear"
color="dark"
(click)="presentModalMarkdown(not)"
>
View Details
</ion-button>
<ion-button
*ngIf="not.packageId && packageData[not.packageId]"
slot="end"

View File

@@ -1,7 +1,11 @@
import { Component } from '@angular/core'
import { ActivatedRoute } from '@angular/router'
import { AlertController, ModalController } from '@ionic/angular'
import { ErrorService, LoadingService } from '@start9labs/shared'
import {
ErrorService,
LoadingService,
MarkdownComponent,
} from '@start9labs/shared'
import { PatchDB } from 'patch-db-client'
import { first } from 'rxjs'
import { BackupReportPage } from 'src/app/modals/backup-report/backup-report.page'
@@ -115,6 +119,18 @@ export class NotificationsPage {
await modal.present()
}
async presentModalMarkdown(not: ServerNotification<2>) {
const modal = await this.modalCtrl.create({
componentProps: {
title: not.title,
content: not.data,
},
component: MarkdownComponent,
})
await modal.present()
}
async viewFullMessage(header: string, message: string) {
const alert = await this.alertCtrl.create({
header,
@@ -134,7 +150,7 @@ export class NotificationsPage {
}
truncate(message: string): string {
return message.length <= 240 ? message : '...' + message.substr(-240)
return message.length <= 240 ? message : message.substring(0, 160) + '...'
}
getColor({ level }: ServerNotification<number>): string {

View File

@@ -9,6 +9,8 @@ import { configBuilderToSpec } from 'src/app/util/configBuilderToSpec'
import { T, ISB, IST } from '@start9labs/start-sdk'
import { GetPackagesRes } from '@start9labs/marketplace'
import markdown from 'raw-loader!../../../../../shared/assets/markdown/md-sample.md'
const mockMerkleArchiveCommitment: T.MerkleArchiveCommitment = {
rootSighash: 'fakehash',
rootMaxsize: 0,
@@ -759,7 +761,7 @@ export module Mock {
id: 2,
packageId: null,
createdAt: '2019-12-26T14:20:30.872Z',
code: 2,
code: 0,
level: NotificationLevel.Warning,
title: 'SSH Key Added',
message: 'A new SSH key was added. If you did not do this, shit is bad.',
@@ -769,7 +771,7 @@ export module Mock {
id: 3,
packageId: null,
createdAt: '2019-12-26T14:20:30.872Z',
code: 3,
code: 0,
level: NotificationLevel.Info,
title: 'SSH Key Removed',
message: 'A SSH key was removed.',
@@ -779,7 +781,7 @@ export module Mock {
id: 4,
packageId: 'bitcoind',
createdAt: '2019-12-26T14:20:30.872Z',
code: 4,
code: 0,
level: NotificationLevel.Error,
title: 'Service Crashed',
message: new Array(40)
@@ -792,6 +794,16 @@ export module Mock {
.join(''),
data: null,
},
{
id: 5,
packageId: null,
createdAt: '2019-12-26T14:20:30.872Z',
code: 2,
level: NotificationLevel.Success,
title: 'Welcome to StartOS 0.3.6!',
message: 'Click "View Details" to learn all about the new version',
data: markdown,
},
]
export function getServerMetrics() {

View File

@@ -442,6 +442,8 @@ export type NotificationData<T> = T extends 0
? null
: T extends 1
? BackupReport
: T extends 2
? string
: any
export interface BackupReport {

View File

@@ -6,7 +6,6 @@ const version = require('../../../../../../package.json').version
export const mockPatchData: DataModel = {
ui: {
name: `Matt's Server`,
ackWelcome: '1.0.0',
theme: 'Dark',
widgets: BUILT_IN_WIDGETS.filter(
({ id }) =>

View File

@@ -1,13 +1,9 @@
import { Inject, Injectable } from '@angular/core'
import { ModalController } from '@ionic/angular'
import { Observable } from 'rxjs'
import { filter, map, share, switchMap, take, tap } from 'rxjs/operators'
import { filter, map, share, switchMap, take } from 'rxjs/operators'
import { PatchDB } from 'patch-db-client'
import { DataModel } from 'src/app/services/patch-db/data-model'
import { EOSService } from 'src/app/services/eos.service'
import { OSWelcomePage } from 'src/app/modals/os-welcome/os-welcome.page'
import { ConfigService } from 'src/app/services/config.service'
import { ApiService } from 'src/app/services/api/embassy-api.service'
import { MarketplaceService } from 'src/app/services/marketplace.service'
import { AbstractMarketplaceService } from '@start9labs/marketplace'
import { ConnectionService } from 'src/app/services/connection.service'
@@ -27,8 +23,6 @@ export class PatchDataService extends Observable<void> {
if (index === 0) {
// check for updates to StartOS and services
this.checkForUpdates()
// show eos welcome message
this.showEosWelcome(cache.ui.ackWelcome)
}
}),
share(),
@@ -37,9 +31,6 @@ export class PatchDataService extends Observable<void> {
constructor(
private readonly patch: PatchDB<DataModel>,
private readonly eosService: EOSService,
private readonly config: ConfigService,
private readonly modalCtrl: ModalController,
private readonly embassyApi: ApiService,
@Inject(AbstractMarketplaceService)
private readonly marketplaceService: MarketplaceService,
private readonly connection$: ConnectionService,
@@ -52,23 +43,4 @@ export class PatchDataService extends Observable<void> {
this.eosService.loadEos()
this.marketplaceService.getMarketplace$().pipe(take(1)).subscribe()
}
private async showEosWelcome(ackVersion: string): Promise<void> {
if (this.config.skipStartupAlerts || ackVersion === this.config.version) {
return
}
const modal = await this.modalCtrl.create({
component: OSWelcomePage,
presentingElement: await this.modalCtrl.getTop(),
backdropDismiss: false,
})
modal.onWillDismiss().then(() => {
this.embassyApi
.setDbValue<string>(['ackWelcome'], this.config.version)
.catch()
})
await modal.present()
}
}

View File

@@ -7,7 +7,6 @@ export type DataModel = T.Public & {
export interface UIData {
name: string | null
ackWelcome: string // eOS emver
marketplace: UIMarketplaceData
gaming: {
snake: {