Migrate Angular UI from portmaster-ui to desktop/angular. Update Earthfile to build libs, UI and tauri-builtin
This commit is contained in:
1
desktop/angular/src/app/intro/index.ts
Normal file
1
desktop/angular/src/app/intro/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './intro.module';
|
||||
36
desktop/angular/src/app/intro/intro.module.ts
Normal file
36
desktop/angular/src/app/intro/intro.module.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { OverlayModule } from "@angular/cdk/overlay";
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { NgModule } from "@angular/core";
|
||||
import { FormsModule } from "@angular/forms";
|
||||
import { SfngDropDownModule, SfngTipUpModule, StepperConfig } from "@safing/ui";
|
||||
import { ConfigModule } from "../shared/config";
|
||||
import { Step1WelcomeComponent } from "./step-1-welcome";
|
||||
import { Step2TrackersComponent } from "./step-2-trackers";
|
||||
import { Step3DNSComponent } from "./step-3-dns";
|
||||
import { Step4TipupsComponent } from "./step-4-tipups";
|
||||
|
||||
const steps = [
|
||||
Step1WelcomeComponent,
|
||||
Step2TrackersComponent,
|
||||
Step3DNSComponent,
|
||||
Step4TipupsComponent,
|
||||
]
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
OverlayModule,
|
||||
FormsModule,
|
||||
SfngDropDownModule,
|
||||
ConfigModule,
|
||||
SfngTipUpModule,
|
||||
],
|
||||
declarations: steps
|
||||
})
|
||||
export class IntroModule {
|
||||
static Stepper: StepperConfig = {
|
||||
steps: steps,
|
||||
canAbort: (idx) => idx === 0,
|
||||
}
|
||||
}
|
||||
|
||||
1
desktop/angular/src/app/intro/step-1-welcome/index.ts
Normal file
1
desktop/angular/src/app/intro/step-1-welcome/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './step-1-welcome';
|
||||
@@ -0,0 +1,14 @@
|
||||
<h1>Portmaster Protects Your Privacy</h1>
|
||||
|
||||
<p>
|
||||
Portmaster enhances your privacy with powerful defaults - no configuration needed! Of course you can customize
|
||||
everything to your specific needs.
|
||||
</p>
|
||||
|
||||
<!-- This card does not use the default button template -->
|
||||
<ng-template #buttonTemplate>
|
||||
<button class="self-center w-56 py-2 mb-6 rounded-full bg-blue hover:bg-blue hover:bg-opacity-75"
|
||||
(click)="stepRef.next()">
|
||||
Quick Setup
|
||||
</button>
|
||||
</ng-template>
|
||||
@@ -0,0 +1,22 @@
|
||||
import { ChangeDetectionStrategy, Component, Inject, TemplateRef, ViewChild } from "@angular/core";
|
||||
import { Step, StepRef, STEP_REF } from "@safing/ui";
|
||||
import { of } from "rxjs";
|
||||
|
||||
@Component({
|
||||
templateUrl: './step-1-welcome.html',
|
||||
styleUrls: ['../step.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class Step1WelcomeComponent implements Step {
|
||||
validChange = of(true)
|
||||
|
||||
readonly nextButtonLabel = 'Quick Setup';
|
||||
|
||||
@ViewChild('buttonTemplate', { static: true })
|
||||
buttonTemplate!: TemplateRef<any>;
|
||||
|
||||
constructor(
|
||||
@Inject(STEP_REF) public stepRef: StepRef<void>,
|
||||
) { }
|
||||
}
|
||||
|
||||
1
desktop/angular/src/app/intro/step-2-trackers/index.ts
Normal file
1
desktop/angular/src/app/intro/step-2-trackers/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './step-2-trackers'
|
||||
@@ -0,0 +1,11 @@
|
||||
<h1>Trackers Are Blocked System-Wide</h1>
|
||||
|
||||
<p>Portmaster automatically blocks ads, trackers and malware hosts on your whole device. Portmaster knows what to block
|
||||
through trusted domain lists, which are also used by Ad-Blockers in browsers, etc. You can always customize this in
|
||||
the settings.</p>
|
||||
|
||||
<sfng-dropdown label="Customize" class="w-full" maxHeight="300px" maxWidth="600px" offsetY="0">
|
||||
<app-generic-setting class="h-full" [setting]="setting" [attr.id]="setting?.Key" (save)="saveSetting($event)"
|
||||
enableActiveBorder="false" showHeader="false">
|
||||
</app-generic-setting>
|
||||
</sfng-dropdown>
|
||||
@@ -0,0 +1,48 @@
|
||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, DestroyRef, ElementRef, OnInit, inject } from "@angular/core";
|
||||
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
|
||||
import { ConfigService, Setting } from "@safing/portmaster-api";
|
||||
import { Step } from "@safing/ui";
|
||||
import { of } from "rxjs";
|
||||
import { mergeMap } from "rxjs/operators";
|
||||
import { SaveSettingEvent } from "src/app/shared/config/generic-setting";
|
||||
|
||||
@Component({
|
||||
templateUrl: './step-2-trackers.html',
|
||||
styleUrls: ['../step.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class Step2TrackersComponent implements Step, OnInit {
|
||||
private destroyRef = inject(DestroyRef);
|
||||
|
||||
validChange = of(true)
|
||||
|
||||
setting: Setting | null = null;
|
||||
|
||||
constructor(
|
||||
public configService: ConfigService,
|
||||
public readonly elementRef: ElementRef,
|
||||
private cdr: ChangeDetectorRef,
|
||||
) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.configService.get('filter/lists')
|
||||
.pipe(
|
||||
mergeMap(setting => {
|
||||
this.setting = setting;
|
||||
|
||||
return this.configService.watch(setting.Key)
|
||||
}),
|
||||
takeUntilDestroyed(this.destroyRef),
|
||||
)
|
||||
.subscribe(value => {
|
||||
this.setting!.Value = value;
|
||||
|
||||
this.cdr.markForCheck();
|
||||
});
|
||||
}
|
||||
|
||||
saveSetting(event: SaveSettingEvent) {
|
||||
this.configService.save(event.key, event.value)
|
||||
.subscribe()
|
||||
}
|
||||
}
|
||||
1
desktop/angular/src/app/intro/step-3-dns/index.ts
Normal file
1
desktop/angular/src/app/intro/step-3-dns/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './step-3-dns'
|
||||
17
desktop/angular/src/app/intro/step-3-dns/step-3-dns.html
Normal file
17
desktop/angular/src/app/intro/step-3-dns/step-3-dns.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<h1>Secure DNS for All Connections</h1>
|
||||
|
||||
<p>Portmaster automatically encrypts all your DNS queries to safeguard them from prying eyes. Portmaster sets a default
|
||||
provider, but you can always switch to a custom DNS-over-TLS provider in the global settings.</p>
|
||||
|
||||
<sfng-dropdown label="Customize" class="w-full" maxHeight="300px" maxWidth="600px" offsetY="0">
|
||||
<div class="flex flex-wrap items-center justify-center w-full gap-6 px-8 py-8">
|
||||
<button *ngFor="let button of quickSettings" [style.minWidth]="'6rem'" (click)="applyQuickSetting(button)"
|
||||
[disabled]="isCustomValue" [class.bg-blue]="button.active" class="px-4 py-3">
|
||||
{{ button.Name }}
|
||||
</button>
|
||||
|
||||
<button class="w-24 px-4 py-3 bg-blue" *ngIf="isCustomValue">
|
||||
Custom
|
||||
</button>
|
||||
</div>
|
||||
</sfng-dropdown>
|
||||
106
desktop/angular/src/app/intro/step-3-dns/step-3-dns.ts
Normal file
106
desktop/angular/src/app/intro/step-3-dns/step-3-dns.ts
Normal file
@@ -0,0 +1,106 @@
|
||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, DestroyRef, ElementRef, OnInit, inject } from "@angular/core";
|
||||
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
|
||||
import { ConfigService, QuickSetting, Setting, applyQuickSetting } from "@safing/portmaster-api";
|
||||
import { Step } from "@safing/ui";
|
||||
import { of } from "rxjs";
|
||||
import { mergeMap } from "rxjs/operators";
|
||||
import { SaveSettingEvent } from "src/app/shared/config/generic-setting";
|
||||
|
||||
interface QuickSettingModel extends QuickSetting<any> {
|
||||
active: boolean;
|
||||
}
|
||||
|
||||
@Component({
|
||||
templateUrl: './step-3-dns.html',
|
||||
styleUrls: ['../step.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class Step3DNSComponent implements Step, OnInit {
|
||||
private destroyRef = inject(DestroyRef);
|
||||
|
||||
validChange = of(true)
|
||||
|
||||
setting: Setting | null = null;
|
||||
quickSettings: QuickSettingModel[] = [];
|
||||
isCustomValue = false;
|
||||
|
||||
constructor(
|
||||
public configService: ConfigService,
|
||||
public readonly elementRef: ElementRef,
|
||||
private cdr: ChangeDetectorRef,
|
||||
) { }
|
||||
|
||||
private getQuickSettings(): QuickSettingModel[] {
|
||||
if (!this.setting) {
|
||||
return [];
|
||||
}
|
||||
|
||||
let val = this.setting.Annotations["safing/portbase:ui:quick-setting"];
|
||||
if (val === undefined) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!Array.isArray(val)) {
|
||||
return [{
|
||||
...val,
|
||||
active: false,
|
||||
}]
|
||||
}
|
||||
|
||||
return val.map(v => ({
|
||||
...v,
|
||||
active: false,
|
||||
}))
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.configService.get('dns/nameservers')
|
||||
.pipe(
|
||||
mergeMap(setting => {
|
||||
this.setting = setting;
|
||||
this.quickSettings = this.getQuickSettings();
|
||||
return this.configService.watch(setting.Key)
|
||||
}),
|
||||
takeUntilDestroyed(this.destroyRef),
|
||||
)
|
||||
.subscribe(value => {
|
||||
this.setting!.Value = value;
|
||||
|
||||
let hasActive = false;
|
||||
this.isCustomValue = false;
|
||||
|
||||
this.quickSettings.forEach(setting => {
|
||||
if (this.setting?.Value !== undefined && JSON.stringify(this.setting.Value) === JSON.stringify(setting.Value)) {
|
||||
setting.active = true;
|
||||
hasActive = true;
|
||||
} else {
|
||||
setting.active = false;
|
||||
}
|
||||
});
|
||||
|
||||
if (!hasActive) {
|
||||
if (this.setting?.Value !== undefined && JSON.stringify(this.setting!.Value) !== JSON.stringify(this.setting!.DefaultValue)) {
|
||||
this.isCustomValue = true;
|
||||
} else if (this.quickSettings.length > 0) {
|
||||
this.quickSettings[0].active = true;
|
||||
}
|
||||
}
|
||||
|
||||
this.cdr.markForCheck();
|
||||
});
|
||||
}
|
||||
|
||||
saveSetting(event: SaveSettingEvent) {
|
||||
this.configService.save(event.key, event.value)
|
||||
.subscribe()
|
||||
}
|
||||
|
||||
applyQuickSetting(action: QuickSetting<any>) {
|
||||
const newValue = applyQuickSetting(
|
||||
this.setting!.Value || this.setting!.DefaultValue,
|
||||
action,
|
||||
)
|
||||
this.configService.save(this.setting!.Key, newValue)
|
||||
.subscribe();
|
||||
}
|
||||
}
|
||||
1
desktop/angular/src/app/intro/step-4-tipups/index.ts
Normal file
1
desktop/angular/src/app/intro/step-4-tipups/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './step-4-tipups'
|
||||
@@ -0,0 +1,11 @@
|
||||
<h1>Learn More as You Explore</h1>
|
||||
|
||||
<p>Portmaster has a lot more to offer. When you decide to dive deeper you can always click on an information icon to
|
||||
learn more about a certain feature. Look out for those!</p>
|
||||
|
||||
<div class="flex flex-col items-center justify-center gap-1 p-8 text-xxs">
|
||||
<span class="text-tertiary">Click Me!</span>
|
||||
<div class="flex items-center justify-center px-4 py-4 bg-gray-400 rounded">
|
||||
<sfng-tipup class="transform scale-125" key="introTipup"></sfng-tipup>
|
||||
</div>
|
||||
</div>
|
||||
12
desktop/angular/src/app/intro/step-4-tipups/step-4-tipups.ts
Normal file
12
desktop/angular/src/app/intro/step-4-tipups/step-4-tipups.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { ChangeDetectionStrategy, Component } from "@angular/core";
|
||||
import { Step } from "@safing/ui";
|
||||
import { of } from "rxjs";
|
||||
|
||||
@Component({
|
||||
templateUrl: './step-4-tipups.html',
|
||||
styleUrls: ['../step.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class Step4TipupsComponent implements Step {
|
||||
validChange = of(true)
|
||||
}
|
||||
11
desktop/angular/src/app/intro/step.scss
Normal file
11
desktop/angular/src/app/intro/step.scss
Normal file
@@ -0,0 +1,11 @@
|
||||
:host {
|
||||
@apply flex flex-col items-center justify-center;
|
||||
}
|
||||
|
||||
h1 {
|
||||
@apply text-primary text-2xl font-medium capitalize text-center py-5;
|
||||
}
|
||||
|
||||
p {
|
||||
@apply text-tertiary text-sm font-medium text-center;
|
||||
}
|
||||
Reference in New Issue
Block a user