mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 02:11:53 +00:00
adjust service marketplace button for installation source relevance (#1571)
* adjust service marketplace button for installation source relevance * cleanup * show marketplace name instead of url; cleanup from PR feedback * fix spacing * further cleanup
This commit is contained in:
@@ -36,3 +36,16 @@ export function debounce(delay: number = 300): MethodDecorator {
|
||||
return descriptor
|
||||
}
|
||||
}
|
||||
|
||||
export function removeTrailingSlash(word: string): string {
|
||||
return word.replace(/\/+$/, '')
|
||||
}
|
||||
|
||||
export function isValidHttpUrl(string: string): boolean {
|
||||
try {
|
||||
const _ = new URL(string)
|
||||
return true
|
||||
} catch (_) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,3 +111,11 @@ ion-modal::part(content) {
|
||||
.montserrat {
|
||||
font-family: 'Montserrat', sans-serif !important;
|
||||
}
|
||||
|
||||
.color-success-shade {
|
||||
color: var(--ion-color-success-shade)
|
||||
}
|
||||
|
||||
.color-primary-shade {
|
||||
color: var(--ion-color-primary-shade)
|
||||
}
|
||||
@@ -24,7 +24,9 @@
|
||||
[dependencies]="dependencies"
|
||||
></app-show-dependencies>
|
||||
<!-- ** menu ** -->
|
||||
<app-show-menu [buttons]="pkg | toButtons"></app-show-menu>
|
||||
<app-show-menu
|
||||
[buttons]="pkg | toButtons: (currentMarketplace$ | async): (altMarketplaceData$ | async)"
|
||||
></app-show-menu>
|
||||
</ng-container>
|
||||
</ion-item-group>
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core'
|
||||
import { ChangeDetectionStrategy, Component, Inject } from '@angular/core'
|
||||
import { NavController } from '@ionic/angular'
|
||||
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
|
||||
import {
|
||||
PackageDataEntry,
|
||||
PackageMainStatus,
|
||||
PackageState,
|
||||
UIMarketplaceData,
|
||||
} from 'src/app/services/patch-db/data-model'
|
||||
import {
|
||||
PackageStatus,
|
||||
@@ -17,6 +18,12 @@ import {
|
||||
import { map, startWith, filter } from 'rxjs/operators'
|
||||
import { ActivatedRoute } from '@angular/router'
|
||||
import { getPkgId } from '@start9labs/shared'
|
||||
import { MarketplaceService } from 'src/app/services/marketplace.service'
|
||||
import {
|
||||
AbstractMarketplaceService,
|
||||
Marketplace,
|
||||
} from '@start9labs/marketplace'
|
||||
import { Observable } from 'rxjs'
|
||||
|
||||
const STATES = [
|
||||
PackageState.Installing,
|
||||
@@ -53,6 +60,12 @@ export class AppShowPage {
|
||||
),
|
||||
)
|
||||
|
||||
readonly currentMarketplace$: Observable<Marketplace> =
|
||||
this.marketplaceService.getMarketplace()
|
||||
|
||||
readonly altMarketplaceData$: Observable<UIMarketplaceData | undefined> =
|
||||
this.marketplaceService.getAltMarketplace()
|
||||
|
||||
readonly connectionFailure$ = this.connectionService
|
||||
.watchFailure$()
|
||||
.pipe(map(failure => failure !== ConnectionFailure.None))
|
||||
@@ -62,6 +75,8 @@ export class AppShowPage {
|
||||
private readonly navCtrl: NavController,
|
||||
private readonly patch: PatchDbService,
|
||||
private readonly connectionService: ConnectionService,
|
||||
@Inject(AbstractMarketplaceService)
|
||||
private readonly marketplaceService: MarketplaceService,
|
||||
) {}
|
||||
|
||||
isInstalled(
|
||||
|
||||
@@ -2,12 +2,19 @@ import { Inject, Pipe, PipeTransform } from '@angular/core'
|
||||
import { ActivatedRoute } from '@angular/router'
|
||||
import { DOCUMENT } from '@angular/common'
|
||||
import { AlertController, ModalController, NavController } from '@ionic/angular'
|
||||
import { MarkdownComponent } from '@start9labs/shared'
|
||||
import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
|
||||
import {
|
||||
isValidHttpUrl,
|
||||
MarkdownComponent,
|
||||
removeTrailingSlash,
|
||||
} from '@start9labs/shared'
|
||||
import {
|
||||
PackageDataEntry,
|
||||
UIMarketplaceData,
|
||||
} from 'src/app/services/patch-db/data-model'
|
||||
import { ModalService } from 'src/app/services/modal.service'
|
||||
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
||||
import { from } from 'rxjs'
|
||||
|
||||
import { Marketplace } from '@start9labs/marketplace'
|
||||
export interface Button {
|
||||
title: string
|
||||
description: string
|
||||
@@ -30,7 +37,11 @@ export class ToButtonsPipe implements PipeTransform {
|
||||
private readonly apiService: ApiService,
|
||||
) {}
|
||||
|
||||
transform(pkg: PackageDataEntry): Button[] {
|
||||
transform(
|
||||
pkg: PackageDataEntry,
|
||||
currentMarketplace: Marketplace | null,
|
||||
altMarketplaces: UIMarketplaceData | null | undefined,
|
||||
): Button[] {
|
||||
const pkgTitle = pkg.manifest.title
|
||||
|
||||
return [
|
||||
@@ -87,7 +98,7 @@ export class ToButtonsPipe implements PipeTransform {
|
||||
icon: 'receipt-outline',
|
||||
},
|
||||
// view in marketplace
|
||||
this.viewInMarketplaceButton(pkg),
|
||||
this.viewInMarketplaceButton(pkg, currentMarketplace, altMarketplaces),
|
||||
// donate
|
||||
{
|
||||
action: () => this.donate(pkg),
|
||||
@@ -112,24 +123,54 @@ export class ToButtonsPipe implements PipeTransform {
|
||||
await modal.present()
|
||||
}
|
||||
|
||||
private viewInMarketplaceButton(pkg: PackageDataEntry): Button {
|
||||
return pkg.installed?.['marketplace-url']
|
||||
? {
|
||||
private viewInMarketplaceButton(
|
||||
pkg: PackageDataEntry,
|
||||
currentMarketplace: Marketplace | null,
|
||||
altMarketplaces: UIMarketplaceData | null | undefined,
|
||||
): Button {
|
||||
const pkgMarketplace = pkg.installed?.['marketplace-url']
|
||||
// default button if package marketplace and current marketplace are the same
|
||||
let button: Button = {
|
||||
title: 'Marketplace',
|
||||
icon: 'storefront-outline',
|
||||
action: () =>
|
||||
this.navCtrl.navigateForward([`marketplace/${pkg.manifest.id}`]),
|
||||
title: 'Marketplace',
|
||||
disabled: false,
|
||||
description: 'View service in marketplace',
|
||||
icon: 'storefront-outline',
|
||||
}
|
||||
: {
|
||||
disabled: true,
|
||||
action: () => {},
|
||||
title: 'Marketplace',
|
||||
description:
|
||||
'This package has been side-loaded and is not available in the Start9 Marketplace',
|
||||
icon: 'storefront-outline',
|
||||
if (!pkgMarketplace) {
|
||||
button.disabled = true
|
||||
button.description = 'This package was not installed from a marketplace.'
|
||||
button.action = () => {}
|
||||
} else if (
|
||||
pkgMarketplace &&
|
||||
currentMarketplace &&
|
||||
removeTrailingSlash(pkgMarketplace) !==
|
||||
removeTrailingSlash(currentMarketplace.url)
|
||||
) {
|
||||
// attempt to get name for pkg marketplace
|
||||
let pkgTitle = removeTrailingSlash(pkgMarketplace)
|
||||
if (altMarketplaces) {
|
||||
const nameOptions = Object.values(
|
||||
altMarketplaces['known-hosts'],
|
||||
).filter(m => m.url === pkgTitle)
|
||||
if (nameOptions.length) {
|
||||
// if multiple of the same url exist, they will have the same name, so fine to grab first
|
||||
pkgTitle = nameOptions[0].name
|
||||
}
|
||||
}
|
||||
let marketplaceTitle = removeTrailingSlash(currentMarketplace.url)
|
||||
// if we found a name for the pkg marketplace, use the name of the currently connected marketplace
|
||||
if (!isValidHttpUrl(pkgTitle)) {
|
||||
marketplaceTitle = currentMarketplace.name
|
||||
}
|
||||
|
||||
button.action = () =>
|
||||
this.differentMarketplaceAction(pkgTitle, marketplaceTitle)
|
||||
button.description = 'Service was installed from a different marketplace'
|
||||
}
|
||||
return button
|
||||
}
|
||||
|
||||
private async donate({ manifest }: PackageDataEntry): Promise<void> {
|
||||
const url = manifest['donation-url']
|
||||
@@ -143,4 +184,28 @@ export class ToButtonsPipe implements PipeTransform {
|
||||
await alert.present()
|
||||
}
|
||||
}
|
||||
private async differentMarketplaceAction(pkgM: string, currentM: string) {
|
||||
const alert = await this.alertCtrl.create({
|
||||
header: 'Marketplace Conflict',
|
||||
message: `This service was installed from:
|
||||
<br><br>
|
||||
<span class="courier-new color-success-shade">${pkgM}</span>
|
||||
<br><br>but you are currently connected to:<br><br>
|
||||
<span class="courier-new color-primary-shade">${currentM}</span>
|
||||
<br><br>
|
||||
To view the marketplace listing for this service, visit your Marketplace Settings and change marketplaces.`,
|
||||
buttons: [
|
||||
{
|
||||
text: 'Cancel',
|
||||
role: 'cancel',
|
||||
},
|
||||
{
|
||||
text: 'Go to Settings',
|
||||
handler: () => this.navCtrl.navigateForward(['embassy/marketplaces']),
|
||||
cssClass: 'enter-click',
|
||||
},
|
||||
],
|
||||
})
|
||||
await alert.present()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,6 +92,10 @@ export class MarketplaceService extends AbstractMarketplaceService {
|
||||
return this.marketplace$
|
||||
}
|
||||
|
||||
getAltMarketplace(): Observable<UIMarketplaceData | undefined> {
|
||||
return this.altMarketplaceData$
|
||||
}
|
||||
|
||||
getCategories(): Observable<string[]> {
|
||||
return this.categories$
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
export async function copyToClipboard(str: string): Promise<boolean> {
|
||||
if (window.isSecureContext) {
|
||||
return navigator.clipboard.writeText(str)
|
||||
return navigator.clipboard
|
||||
.writeText(str)
|
||||
.then(() => {
|
||||
return true
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user