mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 02:11:53 +00:00
Better Updates Tab and updates count (#2151)
* wip * should be working now * delete unused function * delete 2 more unused functions * update fixture to include beta registry * address comments * wait for connection to get local packages
This commit is contained in:
committed by
Aiden McClelland
parent
62f78e4312
commit
4d3df867da
@@ -45,10 +45,6 @@ export function isValidHttpUrl(url: string): boolean {
|
||||
}
|
||||
}
|
||||
|
||||
export function getUrlHostname(url: string): string {
|
||||
return new URL(url).hostname
|
||||
}
|
||||
|
||||
export function toUrl(text: string | null | undefined): string {
|
||||
try {
|
||||
const url = new URL(text as string)
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { ChangeDetectionStrategy, Component, Inject } from '@angular/core'
|
||||
import { EOSService } from '../../services/eos.service'
|
||||
import { PatchDB } from 'patch-db-client'
|
||||
import { combineLatest, map, Observable, of, startWith } from 'rxjs'
|
||||
import { combineLatest, filter, first, map, Observable, switchMap } from 'rxjs'
|
||||
import { AbstractMarketplaceService } from '@start9labs/marketplace'
|
||||
import { MarketplaceService } from 'src/app/services/marketplace.service'
|
||||
import { DataModel } from 'src/app/services/patch-db/data-model'
|
||||
import { SplitPaneTracker } from 'src/app/services/split-pane.service'
|
||||
import { Emver } from '@start9labs/shared'
|
||||
import { marketplaceSame, versionLower } from '../../pages/updates/updates.page'
|
||||
import { ConnectionService } from 'src/app/services/connection.service'
|
||||
|
||||
@Component({
|
||||
selector: 'app-menu',
|
||||
@@ -53,23 +53,31 @@ export class MenuComponent {
|
||||
|
||||
readonly showEOSUpdate$ = this.eosService.showUpdate$
|
||||
|
||||
private readonly local$ = this.connectionService.connected$.pipe(
|
||||
filter(Boolean),
|
||||
switchMap(() => this.patch.watch$('package-data')),
|
||||
first(),
|
||||
)
|
||||
|
||||
readonly updateCount$: Observable<number> = combineLatest([
|
||||
this.marketplaceService.getMarketplace$(),
|
||||
this.patch.watch$('package-data'),
|
||||
this.marketplaceService.getMarketplace$(true),
|
||||
this.local$,
|
||||
]).pipe(
|
||||
map(([marketplace, local]) =>
|
||||
Object.entries(marketplace).reduce(
|
||||
(length, [url, store]) =>
|
||||
length +
|
||||
(store?.packages.filter(
|
||||
({ manifest }) =>
|
||||
marketplaceSame(manifest, local, url) &&
|
||||
versionLower(manifest, local, this.emver),
|
||||
).length || 0),
|
||||
0,
|
||||
),
|
||||
Object.entries(marketplace).reduce((list, [_, store]) => {
|
||||
store?.packages.forEach(({ manifest: { id, version } }) => {
|
||||
if (
|
||||
this.emver.compare(
|
||||
version,
|
||||
local[id]?.installed?.manifest.version || '',
|
||||
) === 1
|
||||
)
|
||||
list.add(id)
|
||||
})
|
||||
return list
|
||||
}, new Set<string>()),
|
||||
),
|
||||
startWith(0),
|
||||
map(list => list.size),
|
||||
)
|
||||
|
||||
readonly sidebarOpen$ = this.splitPane.sidebarOpen$
|
||||
@@ -81,5 +89,6 @@ export class MenuComponent {
|
||||
private readonly marketplaceService: MarketplaceService,
|
||||
private readonly splitPane: SplitPaneTracker,
|
||||
private readonly emver: Emver,
|
||||
private readonly connectionService: ConnectionService,
|
||||
) {}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { ActivatedRoute } from '@angular/router'
|
||||
import { ModalController } from '@ionic/angular'
|
||||
import { AbstractMarketplaceService } from '@start9labs/marketplace'
|
||||
import { PatchDB } from 'patch-db-client'
|
||||
import { filter, map } from 'rxjs'
|
||||
import { map } from 'rxjs'
|
||||
import { MarketplaceSettingsPage } from 'src/app/modals/marketplace-settings/marketplace-settings.page'
|
||||
import { ConfigService } from 'src/app/services/config.service'
|
||||
import { MarketplaceService } from 'src/app/services/marketplace.service'
|
||||
@@ -85,9 +85,6 @@ export class MarketplaceListPage {
|
||||
const modal = await this.modalCtrl.create({
|
||||
component: MarketplaceSettingsPage,
|
||||
})
|
||||
modal.onDidDismiss().then(res => {
|
||||
console.log(res)
|
||||
})
|
||||
await modal.present()
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
*ngIf="data.marketplace[host.url]?.packages as packages else loading"
|
||||
>
|
||||
<ng-container
|
||||
*ngIf="packages | filterUpdates : data.localPkgs : host.url as updates"
|
||||
*ngIf="packages | filterUpdates : data.localPkgs as updates"
|
||||
>
|
||||
<div *ngFor="let pkg of updates" class="item-container">
|
||||
<ion-item lines="none">
|
||||
|
||||
@@ -14,9 +14,9 @@ import {
|
||||
MarketplacePkg,
|
||||
StoreIdentity,
|
||||
} from '@start9labs/marketplace'
|
||||
import { Emver, isEmptyObject, sameUrl } from '@start9labs/shared'
|
||||
import { Emver, isEmptyObject } from '@start9labs/shared'
|
||||
import { Pipe, PipeTransform } from '@angular/core'
|
||||
import { combineLatest, map, Observable } from 'rxjs'
|
||||
import { combineLatest, Observable } from 'rxjs'
|
||||
import {
|
||||
AlertController,
|
||||
LoadingController,
|
||||
@@ -25,8 +25,6 @@ import {
|
||||
import { hasCurrentDeps } from 'src/app/util/has-deps'
|
||||
import { getAllPackages } from 'src/app/util/get-package-data'
|
||||
import { Breakages } from 'src/app/services/api/api.types'
|
||||
import { ClientStorageService } from 'src/app/services/client-storage.service'
|
||||
import { ConfigService } from 'src/app/services/config.service'
|
||||
|
||||
interface UpdatesData {
|
||||
hosts: StoreIdentity[]
|
||||
@@ -41,20 +39,8 @@ interface UpdatesData {
|
||||
styleUrls: ['updates.page.scss'],
|
||||
})
|
||||
export class UpdatesPage {
|
||||
readonly hosts$ = combineLatest([
|
||||
this.clientStorageService.showDevTools$,
|
||||
this.marketplaceService.getKnownHosts$(),
|
||||
]).pipe(
|
||||
map(([devMode, knownHosts]) => {
|
||||
if (devMode) return knownHosts
|
||||
return knownHosts.filter(
|
||||
({ url }) => !url.includes('alpha') && !url.includes('beta'),
|
||||
)
|
||||
}),
|
||||
)
|
||||
|
||||
readonly data$: Observable<UpdatesData> = combineLatest({
|
||||
hosts: this.hosts$,
|
||||
hosts: this.marketplaceService.getKnownHosts$(true),
|
||||
marketplace: this.marketplaceService.getMarketplace$(),
|
||||
localPkgs: this.patch.watch$('package-data'),
|
||||
errors: this.marketplaceService.getRequestErrors$(),
|
||||
@@ -70,8 +56,6 @@ export class UpdatesPage {
|
||||
private readonly navCtrl: NavController,
|
||||
private readonly loadingCtrl: LoadingController,
|
||||
private readonly alertCtrl: AlertController,
|
||||
private readonly clientStorageService: ClientStorageService,
|
||||
private readonly config: ConfigService,
|
||||
) {}
|
||||
|
||||
viewInMarketplace(pkg: PackageDataEntry) {
|
||||
@@ -191,33 +175,18 @@ export class FilterUpdatesPipe implements PipeTransform {
|
||||
|
||||
transform(
|
||||
pkgs: MarketplacePkg[],
|
||||
local: Record<string, PackageDataEntry> = {},
|
||||
url: string,
|
||||
local: Record<string, PackageDataEntry | undefined>,
|
||||
): MarketplacePkg[] {
|
||||
return pkgs.filter(
|
||||
({ manifest }) =>
|
||||
marketplaceSame(manifest, local, url) &&
|
||||
versionLower(manifest, local, this.emver),
|
||||
)
|
||||
return pkgs.filter(({ manifest }) => {
|
||||
const localPkg = local[manifest.id]
|
||||
|
||||
return (
|
||||
localPkg?.state === PackageState.Updating ||
|
||||
this.emver.compare(
|
||||
manifest.version,
|
||||
localPkg?.installed?.manifest.version || '',
|
||||
) === 1
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export function marketplaceSame(
|
||||
{ id }: MarketplaceManifest,
|
||||
local: Record<string, PackageDataEntry>,
|
||||
url: string,
|
||||
): boolean {
|
||||
const localUrl = local[id]?.installed?.['marketplace-url']
|
||||
return sameUrl(localUrl, url)
|
||||
}
|
||||
|
||||
export function versionLower(
|
||||
{ version, id }: MarketplaceManifest,
|
||||
local: Record<string, PackageDataEntry>,
|
||||
emver: Emver,
|
||||
): boolean {
|
||||
return (
|
||||
local[id].state === PackageState.Updating ||
|
||||
emver.compare(version, local[id].installed?.manifest.version || '') === 1
|
||||
)
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ export const mockPatchData: DataModel = {
|
||||
name: 'Start9 Registry',
|
||||
},
|
||||
'https://community-registry.start9.com/': {},
|
||||
'https://dark9-marketplace.com/': {
|
||||
'https://beta-registry.start9.com/': {
|
||||
name: 'Dark9',
|
||||
},
|
||||
},
|
||||
|
||||
@@ -34,6 +34,7 @@ import {
|
||||
} from 'rxjs/operators'
|
||||
import { ConfigService } from './config.service'
|
||||
import { sameUrl } from '@start9labs/shared'
|
||||
import { ClientStorageService } from './client-storage.service'
|
||||
|
||||
@Injectable()
|
||||
export class MarketplaceService implements AbstractMarketplaceService {
|
||||
@@ -55,6 +56,20 @@ export class MarketplaceService implements AbstractMarketplaceService {
|
||||
}),
|
||||
)
|
||||
|
||||
private readonly filteredKnownHosts$: Observable<StoreIdentity[]> =
|
||||
combineLatest([
|
||||
this.clientStorageService.showDevTools$,
|
||||
this.knownHosts$,
|
||||
]).pipe(
|
||||
map(([devMode, knownHosts]) =>
|
||||
devMode
|
||||
? knownHosts
|
||||
: knownHosts.filter(
|
||||
({ url }) => !url.includes('alpha') && !url.includes('beta'),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
private readonly selectedHost$: Observable<StoreIdentity> = this.patch
|
||||
.watch$('ui', 'marketplace')
|
||||
.pipe(
|
||||
@@ -93,6 +108,24 @@ export class MarketplaceService implements AbstractMarketplaceService {
|
||||
shareReplay(1),
|
||||
)
|
||||
|
||||
private readonly filteredMarketplace$ = combineLatest([
|
||||
this.clientStorageService.showDevTools$,
|
||||
this.marketplace$,
|
||||
]).pipe(
|
||||
map(([devMode, marketplace]) =>
|
||||
Object.entries(marketplace).reduce(
|
||||
(filtered, [url, store]) =>
|
||||
!devMode && (url.includes('alpha') || url.includes('beta'))
|
||||
? filtered
|
||||
: {
|
||||
[url]: store,
|
||||
...filtered,
|
||||
},
|
||||
{} as Marketplace,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
private readonly selectedStore$: Observable<StoreData> =
|
||||
this.selectedHost$.pipe(
|
||||
switchMap(({ url }) =>
|
||||
@@ -110,18 +143,21 @@ export class MarketplaceService implements AbstractMarketplaceService {
|
||||
private readonly api: ApiService,
|
||||
private readonly patch: PatchDB<DataModel>,
|
||||
private readonly config: ConfigService,
|
||||
private readonly clientStorageService: ClientStorageService,
|
||||
) {}
|
||||
|
||||
getKnownHosts$(): Observable<StoreIdentity[]> {
|
||||
return this.knownHosts$
|
||||
getKnownHosts$(filtered = false): Observable<StoreIdentity[]> {
|
||||
// option to filter out hosts containing 'alpha' or 'beta' substrings in registryURL
|
||||
return filtered ? this.filteredKnownHosts$ : this.knownHosts$
|
||||
}
|
||||
|
||||
getSelectedHost$(): Observable<StoreIdentity> {
|
||||
return this.selectedHost$
|
||||
}
|
||||
|
||||
getMarketplace$(): Observable<Marketplace> {
|
||||
return this.marketplace$
|
||||
getMarketplace$(filtered = false): Observable<Marketplace> {
|
||||
// option to filter out hosts containing 'alpha' or 'beta' substrings in registryURL
|
||||
return filtered ? this.filteredMarketplace$ : this.marketplace$
|
||||
}
|
||||
|
||||
getSelectedStore$(): Observable<StoreData> {
|
||||
|
||||
Reference in New Issue
Block a user