mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-04-04 22:39:46 +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
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -110,4 +110,12 @@ ion-modal::part(content) {
|
|||||||
|
|
||||||
.montserrat {
|
.montserrat {
|
||||||
font-family: 'Montserrat', sans-serif !important;
|
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"
|
[dependencies]="dependencies"
|
||||||
></app-show-dependencies>
|
></app-show-dependencies>
|
||||||
<!-- ** menu ** -->
|
<!-- ** 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>
|
</ng-container>
|
||||||
</ion-item-group>
|
</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 { NavController } from '@ionic/angular'
|
||||||
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
|
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
|
||||||
import {
|
import {
|
||||||
PackageDataEntry,
|
PackageDataEntry,
|
||||||
PackageMainStatus,
|
PackageMainStatus,
|
||||||
PackageState,
|
PackageState,
|
||||||
|
UIMarketplaceData,
|
||||||
} from 'src/app/services/patch-db/data-model'
|
} from 'src/app/services/patch-db/data-model'
|
||||||
import {
|
import {
|
||||||
PackageStatus,
|
PackageStatus,
|
||||||
@@ -17,6 +18,12 @@ import {
|
|||||||
import { map, startWith, filter } from 'rxjs/operators'
|
import { map, startWith, filter } from 'rxjs/operators'
|
||||||
import { ActivatedRoute } from '@angular/router'
|
import { ActivatedRoute } from '@angular/router'
|
||||||
import { getPkgId } from '@start9labs/shared'
|
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 = [
|
const STATES = [
|
||||||
PackageState.Installing,
|
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
|
readonly connectionFailure$ = this.connectionService
|
||||||
.watchFailure$()
|
.watchFailure$()
|
||||||
.pipe(map(failure => failure !== ConnectionFailure.None))
|
.pipe(map(failure => failure !== ConnectionFailure.None))
|
||||||
@@ -62,7 +75,9 @@ export class AppShowPage {
|
|||||||
private readonly navCtrl: NavController,
|
private readonly navCtrl: NavController,
|
||||||
private readonly patch: PatchDbService,
|
private readonly patch: PatchDbService,
|
||||||
private readonly connectionService: ConnectionService,
|
private readonly connectionService: ConnectionService,
|
||||||
) { }
|
@Inject(AbstractMarketplaceService)
|
||||||
|
private readonly marketplaceService: MarketplaceService,
|
||||||
|
) {}
|
||||||
|
|
||||||
isInstalled(
|
isInstalled(
|
||||||
{ state }: PackageDataEntry,
|
{ state }: PackageDataEntry,
|
||||||
|
|||||||
@@ -2,12 +2,19 @@ import { Inject, Pipe, PipeTransform } from '@angular/core'
|
|||||||
import { ActivatedRoute } from '@angular/router'
|
import { ActivatedRoute } from '@angular/router'
|
||||||
import { DOCUMENT } from '@angular/common'
|
import { DOCUMENT } from '@angular/common'
|
||||||
import { AlertController, ModalController, NavController } from '@ionic/angular'
|
import { AlertController, ModalController, NavController } from '@ionic/angular'
|
||||||
import { MarkdownComponent } from '@start9labs/shared'
|
import {
|
||||||
import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
|
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 { 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 } from 'rxjs'
|
||||||
|
import { Marketplace } from '@start9labs/marketplace'
|
||||||
export interface Button {
|
export interface Button {
|
||||||
title: string
|
title: string
|
||||||
description: string
|
description: string
|
||||||
@@ -30,7 +37,11 @@ export class ToButtonsPipe implements PipeTransform {
|
|||||||
private readonly apiService: ApiService,
|
private readonly apiService: ApiService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
transform(pkg: PackageDataEntry): Button[] {
|
transform(
|
||||||
|
pkg: PackageDataEntry,
|
||||||
|
currentMarketplace: Marketplace | null,
|
||||||
|
altMarketplaces: UIMarketplaceData | null | undefined,
|
||||||
|
): Button[] {
|
||||||
const pkgTitle = pkg.manifest.title
|
const pkgTitle = pkg.manifest.title
|
||||||
|
|
||||||
return [
|
return [
|
||||||
@@ -87,7 +98,7 @@ export class ToButtonsPipe implements PipeTransform {
|
|||||||
icon: 'receipt-outline',
|
icon: 'receipt-outline',
|
||||||
},
|
},
|
||||||
// view in marketplace
|
// view in marketplace
|
||||||
this.viewInMarketplaceButton(pkg),
|
this.viewInMarketplaceButton(pkg, currentMarketplace, altMarketplaces),
|
||||||
// donate
|
// donate
|
||||||
{
|
{
|
||||||
action: () => this.donate(pkg),
|
action: () => this.donate(pkg),
|
||||||
@@ -112,23 +123,53 @@ export class ToButtonsPipe implements PipeTransform {
|
|||||||
await modal.present()
|
await modal.present()
|
||||||
}
|
}
|
||||||
|
|
||||||
private viewInMarketplaceButton(pkg: PackageDataEntry): Button {
|
private viewInMarketplaceButton(
|
||||||
return pkg.installed?.['marketplace-url']
|
pkg: PackageDataEntry,
|
||||||
? {
|
currentMarketplace: Marketplace | null,
|
||||||
action: () =>
|
altMarketplaces: UIMarketplaceData | null | undefined,
|
||||||
this.navCtrl.navigateForward([`marketplace/${pkg.manifest.id}`]),
|
): Button {
|
||||||
title: 'Marketplace',
|
const pkgMarketplace = pkg.installed?.['marketplace-url']
|
||||||
description: 'View service in marketplace',
|
// default button if package marketplace and current marketplace are the same
|
||||||
icon: 'storefront-outline',
|
let button: Button = {
|
||||||
}
|
title: 'Marketplace',
|
||||||
: {
|
icon: 'storefront-outline',
|
||||||
disabled: true,
|
action: () =>
|
||||||
action: () => {},
|
this.navCtrl.navigateForward([`marketplace/${pkg.manifest.id}`]),
|
||||||
title: 'Marketplace',
|
disabled: false,
|
||||||
description:
|
description: 'View service in marketplace',
|
||||||
'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> {
|
private async donate({ manifest }: PackageDataEntry): Promise<void> {
|
||||||
@@ -143,4 +184,28 @@ export class ToButtonsPipe implements PipeTransform {
|
|||||||
await alert.present()
|
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$
|
return this.marketplace$
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getAltMarketplace(): Observable<UIMarketplaceData | undefined> {
|
||||||
|
return this.altMarketplaceData$
|
||||||
|
}
|
||||||
|
|
||||||
getCategories(): Observable<string[]> {
|
getCategories(): Observable<string[]> {
|
||||||
return this.categories$
|
return this.categories$
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
export async function copyToClipboard (str: string): Promise<boolean> {
|
export async function copyToClipboard(str: string): Promise<boolean> {
|
||||||
if (window.isSecureContext) {
|
if (window.isSecureContext) {
|
||||||
return navigator.clipboard.writeText(str)
|
return navigator.clipboard
|
||||||
|
.writeText(str)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user