mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-30 20:14:49 +00:00
begin popover for UI launch select
This commit is contained in:
committed by
Aiden McClelland
parent
cb7790ccba
commit
ee9c328606
@@ -6,8 +6,8 @@ import { SharedPipesModule } from '@start9labs/shared'
|
||||
import {
|
||||
AppInterfacesItemComponent,
|
||||
AppInterfacesPage,
|
||||
AddressTypePipe,
|
||||
} from './app-interfaces.page'
|
||||
import { UiPipeModule } from 'src/app/pipes/ui/ui.module'
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
@@ -22,11 +22,8 @@ const routes: Routes = [
|
||||
IonicModule,
|
||||
RouterModule.forChild(routes),
|
||||
SharedPipesModule,
|
||||
UiPipeModule,
|
||||
],
|
||||
declarations: [
|
||||
AppInterfacesPage,
|
||||
AppInterfacesItemComponent,
|
||||
AddressTypePipe,
|
||||
],
|
||||
declarations: [AppInterfacesPage, AppInterfacesItemComponent],
|
||||
})
|
||||
export class AppInterfacesPageModule {}
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
Input,
|
||||
Pipe,
|
||||
PipeTransform,
|
||||
} from '@angular/core'
|
||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
|
||||
import { ActivatedRoute } from '@angular/router'
|
||||
import { ModalController, ToastController } from '@ionic/angular'
|
||||
import { getPkgId, copyToClipboard } from '@start9labs/shared'
|
||||
@@ -80,31 +74,3 @@ export class AppInterfacesItemComponent {
|
||||
await toast.present()
|
||||
}
|
||||
}
|
||||
|
||||
@Pipe({
|
||||
name: 'addressType',
|
||||
})
|
||||
export class AddressTypePipe implements PipeTransform {
|
||||
transform(address: string): string {
|
||||
if (isValidIpv4(address)) return 'IPv4'
|
||||
if (isValidIpv6(address)) return 'IPv6'
|
||||
|
||||
const hostname = new URL(address).hostname
|
||||
if (hostname.endsWith('.onion')) return 'Tor'
|
||||
if (hostname.endsWith('.local')) return 'Local'
|
||||
|
||||
return 'Custom'
|
||||
}
|
||||
}
|
||||
|
||||
function isValidIpv4(address: string): boolean {
|
||||
const regexExp =
|
||||
/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
|
||||
return regexExp.test(address)
|
||||
}
|
||||
|
||||
function isValidIpv6(address: string): boolean {
|
||||
const regexExp =
|
||||
/(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))/gi
|
||||
return regexExp.test(address)
|
||||
}
|
||||
|
||||
@@ -25,10 +25,35 @@
|
||||
slot="end"
|
||||
fill="clear"
|
||||
color="primary"
|
||||
(click)="launchUi($event, installed['address-info'])"
|
||||
(click)="openPopover($event)"
|
||||
[disabled]="status !== 'running'"
|
||||
>
|
||||
<ion-icon slot="icon-only" name="open-outline"></ion-icon>
|
||||
</ion-button>
|
||||
<ion-popover
|
||||
#popover
|
||||
[isOpen]="isPopoverOpen"
|
||||
(didDismiss)="isPopoverOpen = false"
|
||||
mode="ios"
|
||||
type="event"
|
||||
>
|
||||
<ng-template>
|
||||
<ion-content>
|
||||
<ion-item-group>
|
||||
<ng-container
|
||||
*ngFor="let uiAddress of installed['address-info'] | uiAddresses"
|
||||
>
|
||||
<ion-item-divider>{{ uiAddress.name }}</ion-item-divider>
|
||||
<ion-item button *ngFor="let address of uiAddress.addresses">
|
||||
<ion-label>
|
||||
<h2>{{ address | addressType }}</h2>
|
||||
<p>{{ address }}</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
</ng-container>
|
||||
</ion-item-group>
|
||||
</ion-content>
|
||||
</ng-template>
|
||||
</ion-popover>
|
||||
</ng-container>
|
||||
</ion-item>
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
ion-popover {
|
||||
--min-width: 300px;
|
||||
}
|
||||
@@ -1,21 +1,25 @@
|
||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
|
||||
import {
|
||||
InstalledPackageInfo,
|
||||
PackageMainStatus,
|
||||
} from 'src/app/services/patch-db/data-model'
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
Input,
|
||||
ViewChild,
|
||||
} from '@angular/core'
|
||||
import { PackageMainStatus } from 'src/app/services/patch-db/data-model'
|
||||
import { PkgInfo } from 'src/app/util/get-package-info'
|
||||
import { UiLauncherService } from 'src/app/services/ui-launcher.service'
|
||||
|
||||
@Component({
|
||||
selector: 'app-list-pkg',
|
||||
templateUrl: 'app-list-pkg.component.html',
|
||||
styleUrls: ['app-list-pkg.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class AppListPkgComponent {
|
||||
@ViewChild('popover') popover!: HTMLIonPopoverElement
|
||||
|
||||
@Input()
|
||||
pkg!: PkgInfo
|
||||
|
||||
constructor(private readonly launcherService: UiLauncherService) {}
|
||||
isPopoverOpen = false
|
||||
|
||||
get status(): PackageMainStatus {
|
||||
return (
|
||||
@@ -23,9 +27,10 @@ export class AppListPkgComponent {
|
||||
)
|
||||
}
|
||||
|
||||
launchUi(e: Event, addressInfo: InstalledPackageInfo['address-info']): void {
|
||||
openPopover(e: Event): void {
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
this.launcherService.launch(addressInfo)
|
||||
this.popover.event = e
|
||||
this.isPopoverOpen = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { NgModule } from '@angular/core'
|
||||
import { UiPipe } from './ui.pipe'
|
||||
import { UiPipe, UiAddressesPipe, AddressTypePipe } from './ui.pipe'
|
||||
|
||||
@NgModule({
|
||||
declarations: [UiPipe],
|
||||
exports: [UiPipe],
|
||||
declarations: [UiPipe, UiAddressesPipe, AddressTypePipe],
|
||||
exports: [UiPipe, UiAddressesPipe, AddressTypePipe],
|
||||
})
|
||||
export class UiPipeModule {}
|
||||
|
||||
@@ -10,3 +10,47 @@ export class UiPipe implements PipeTransform {
|
||||
return hasUi(addressInfo)
|
||||
}
|
||||
}
|
||||
|
||||
@Pipe({
|
||||
name: 'uiAddresses',
|
||||
})
|
||||
export class UiAddressesPipe implements PipeTransform {
|
||||
transform(
|
||||
addressInfo: InstalledPackageInfo['address-info'],
|
||||
): { name: string; addresses: string[] }[] {
|
||||
return Object.values(addressInfo)
|
||||
.filter(info => info.ui)
|
||||
.map(info => ({
|
||||
name: info.name,
|
||||
addresses: info.addresses,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
@Pipe({
|
||||
name: 'addressType',
|
||||
})
|
||||
export class AddressTypePipe implements PipeTransform {
|
||||
transform(address: string): string {
|
||||
if (isValidIpv4(address)) return 'IPv4'
|
||||
if (isValidIpv6(address)) return 'IPv6'
|
||||
|
||||
const hostname = new URL(address).hostname
|
||||
if (hostname.endsWith('.onion')) return 'Tor'
|
||||
if (hostname.endsWith('.local')) return 'Local'
|
||||
|
||||
return 'Custom'
|
||||
}
|
||||
}
|
||||
|
||||
function isValidIpv4(address: string): boolean {
|
||||
const regexExp =
|
||||
/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
|
||||
return regexExp.test(address)
|
||||
}
|
||||
|
||||
function isValidIpv6(address: string): boolean {
|
||||
const regexExp =
|
||||
/(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))/gi
|
||||
return regexExp.test(address)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user