Customise window decorations, add openfolder action to menu, fix toolbar colours
This commit is contained in:
@@ -1,11 +1,26 @@
|
||||
<mat-toolbar><span>BufPiv</span></mat-toolbar>
|
||||
<mat-toolbar data-tauri-drag-region color="secondary"
|
||||
><h1>BufPiv</h1></mat-toolbar
|
||||
>
|
||||
<mat-sidenav-container autosize>
|
||||
@if(selectedDirectory()) {
|
||||
<mat-sidenav mode="side" opened>
|
||||
<app-file-tree [files]="files()"></app-file-tree>
|
||||
</mat-sidenav>
|
||||
}
|
||||
<mat-sidenav-content>
|
||||
@if (!selectedDirectory) {
|
||||
<button mat-button (click)="selectDirectory()">Open Folder</button>
|
||||
@if (!selectedDirectory()) {
|
||||
<div
|
||||
style="
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
"
|
||||
>
|
||||
<button mat-button (click)="selectDirectory()" style="margin: auto">
|
||||
Open Folder
|
||||
</button>
|
||||
</div>
|
||||
}@else { }
|
||||
</mat-sidenav-content>
|
||||
<!-- TODO: Proto selector (add/remove proto definitinos, select definition for current file) on right side -->
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
mat-toolbar {
|
||||
flex: 0 0 auto;
|
||||
padding-top: 24px;
|
||||
--mat-toolbar-standard-height: 70px;
|
||||
}
|
||||
mat-sidenav-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Component, signal } from '@angular/core';
|
||||
import {
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
signal,
|
||||
} from '@angular/core';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatSidenavModule } from '@angular/material/sidenav';
|
||||
import { RouterOutlet } from '@angular/router';
|
||||
@@ -12,6 +18,8 @@ import {
|
||||
FileTreeComponent,
|
||||
} from './file-tree/file-tree.component';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { listen, UnlistenFn } from '@tauri-apps/api/event';
|
||||
import { OpenFolderMessage } from './messages/openfolder.message';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
@@ -30,9 +38,26 @@ import { MatIconModule } from '@angular/material/icon';
|
||||
],
|
||||
})
|
||||
export class AppComponent {
|
||||
protected selectedDirectory: string | null = null;
|
||||
protected selectedDirectory = signal<string | null>(null);
|
||||
protected files = signal<FileOrFolder[]>([]);
|
||||
|
||||
private unlisten?: UnlistenFn;
|
||||
|
||||
async ngOnInit() {
|
||||
this.unlisten = await listen(
|
||||
'openfolder',
|
||||
async (event: OpenFolderMessage) => {
|
||||
await this.selectDirectory();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
async ngOnDestroy() {
|
||||
if (this.unlisten) {
|
||||
this.unlisten();
|
||||
}
|
||||
}
|
||||
|
||||
async selectDirectory() {
|
||||
const selectedDirectory = await open({
|
||||
directory: true,
|
||||
@@ -40,22 +65,58 @@ export class AppComponent {
|
||||
});
|
||||
if (Array.isArray(selectedDirectory)) {
|
||||
message('Only a single folder can be selected at a time');
|
||||
return;
|
||||
} else {
|
||||
this.selectedDirectory = selectedDirectory;
|
||||
this.selectedDirectory.set(selectedDirectory);
|
||||
}
|
||||
if (this.selectedDirectory) {
|
||||
const entries = await readDir(this.selectedDirectory, {
|
||||
if (selectedDirectory) {
|
||||
const entries = await readDir(selectedDirectory, {
|
||||
recursive: true,
|
||||
});
|
||||
this.files.set(entries.map((entry) => this.mapEntry(entry)));
|
||||
const splitNumbers = /(\d)+|(\D)+/;
|
||||
this.files.set(
|
||||
entries
|
||||
.sort(this.sortFiles(splitNumbers))
|
||||
.map((entry) => this.mapEntry(entry, splitNumbers))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private mapEntry(entry: FileEntry): FileOrFolder {
|
||||
private mapEntry(entry: FileEntry, splitNumbers: RegExp): FileOrFolder {
|
||||
return {
|
||||
isDirectory: entry.children != null,
|
||||
name: entry.name || '',
|
||||
children: entry.children?.map((entry) => this.mapEntry(entry)),
|
||||
children: entry.children?.map((entry) =>
|
||||
this.mapEntry(entry, splitNumbers)
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
private sortFiles =
|
||||
(splitNumbers: RegExp) => (a: FileEntry, b: FileEntry) => {
|
||||
return a.name?.localeCompare(b.name ?? '') ?? 0;
|
||||
// if (!a.name) {
|
||||
// return -1;
|
||||
// }
|
||||
// if (!b.name) {
|
||||
// return 1;
|
||||
// }
|
||||
// const aSplit = splitNumbers.exec(a.name);
|
||||
// const bSplit = splitNumbers.exec(b.name);
|
||||
// if (!aSplit) {
|
||||
// return -1;
|
||||
// }
|
||||
// if (!bSplit) {
|
||||
// return 1;
|
||||
// }
|
||||
// for (
|
||||
// let i = 0;
|
||||
// i < (aSplit.length > bSplit.length ? bSplit.length : aSplit.length);
|
||||
// i++
|
||||
// ) {}
|
||||
// // TODO: Alternative is to iterate through characters in the strings to find numbers, if there isn't a number then return
|
||||
// // locale compare?
|
||||
// // TODO: finish this
|
||||
// return 0;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ interface FileNode {
|
||||
<button mat-icon-button disabled></button>
|
||||
{{ node.file.name }}
|
||||
</mat-tree-node>
|
||||
<mat-tree-node *matTreeNodeDef="let node; when: hasChild">
|
||||
<mat-tree-node *matTreeNodeDef="let node; when: hasChild" matTreeNodeToggle>
|
||||
<button
|
||||
mat-icon-button
|
||||
matTreeNodePadding
|
||||
@@ -51,7 +51,7 @@ interface FileNode {
|
||||
chevron_right }
|
||||
</mat-icon>
|
||||
</button>
|
||||
{{ node.name }}
|
||||
{{ node.file.name }}
|
||||
</mat-tree-node>
|
||||
</mat-tree>`,
|
||||
styleUrl: './file-tree.component.scss',
|
||||
|
||||
1
src/app/messages/openfolder.message.ts
Normal file
1
src/app/messages/openfolder.message.ts
Normal file
@@ -0,0 +1 @@
|
||||
export interface OpenFolderMessage {}
|
||||
@@ -1,141 +0,0 @@
|
||||
// This file was generated by running 'ng generate @angular/material:m3-theme'.
|
||||
// Proceed with caution if making changes to this file.
|
||||
|
||||
@use 'sass:map';
|
||||
@use '@angular/material' as mat;
|
||||
|
||||
// Note: Color palettes are generated from primary: #DF6B85, secondary: #AE868D, tertiary: #B48858, neutral: #988E8F
|
||||
$_palettes: (
|
||||
primary: (
|
||||
0: #000000,
|
||||
10: #3f0015,
|
||||
20: #630828,
|
||||
25: #721633,
|
||||
30: #82233e,
|
||||
35: #912f49,
|
||||
40: #a13a54,
|
||||
50: #c0536c,
|
||||
60: #e06c86,
|
||||
70: #ff86a0,
|
||||
80: #ffb2bf,
|
||||
90: #ffd9de,
|
||||
95: #ffecee,
|
||||
98: #fff8f7,
|
||||
99: #fffbff,
|
||||
100: #ffffff,
|
||||
),
|
||||
secondary: (
|
||||
0: #000000,
|
||||
10: #3f0017,
|
||||
20: #5f112b,
|
||||
25: #6d1d35,
|
||||
30: #7c2940,
|
||||
35: #8b344c,
|
||||
40: #9a4058,
|
||||
50: #b95870,
|
||||
60: #d87189,
|
||||
70: #f78aa3,
|
||||
80: #ffb1c0,
|
||||
90: #ffd9df,
|
||||
95: #ffecee,
|
||||
98: #fff8f7,
|
||||
99: #fffbff,
|
||||
100: #ffffff,
|
||||
),
|
||||
tertiary: (
|
||||
0: #000000,
|
||||
10: #2b1700,
|
||||
20: #482900,
|
||||
25: #573300,
|
||||
30: #673d00,
|
||||
35: #774700,
|
||||
40: #885200,
|
||||
50: #aa6800,
|
||||
60: #c98121,
|
||||
70: #e89b3a,
|
||||
80: #ffb868,
|
||||
90: #ffddbb,
|
||||
95: #ffeedf,
|
||||
98: #fff8f4,
|
||||
99: #fffbff,
|
||||
100: #ffffff,
|
||||
),
|
||||
neutral: (
|
||||
0: #000000,
|
||||
10: #3f0018,
|
||||
20: #5f112c,
|
||||
25: #6d1d37,
|
||||
30: #7c2942,
|
||||
35: #8b344e,
|
||||
40: #9a4059,
|
||||
50: #b85872,
|
||||
60: #d7718b,
|
||||
70: #f78aa5,
|
||||
80: #ffb1c2,
|
||||
90: #ffd9e0,
|
||||
95: #ffecee,
|
||||
98: #fff8f7,
|
||||
99: #fffbff,
|
||||
100: #ffffff,
|
||||
),
|
||||
neutral-variant: (
|
||||
0: #000000,
|
||||
10: #24191a,
|
||||
20: #3a2d2f,
|
||||
25: #46383a,
|
||||
30: #524345,
|
||||
35: #5e4f51,
|
||||
40: #6a5a5c,
|
||||
50: #847375,
|
||||
60: #9f8c8e,
|
||||
70: #baa6a9,
|
||||
80: #d6c2c4,
|
||||
90: #f3dddf,
|
||||
95: #ffecee,
|
||||
98: #fff8f7,
|
||||
99: #fffbff,
|
||||
100: #ffffff,
|
||||
),
|
||||
error: (
|
||||
0: #000000,
|
||||
10: #410002,
|
||||
20: #690005,
|
||||
25: #7e0007,
|
||||
30: #93000a,
|
||||
35: #a80710,
|
||||
40: #ba1a1a,
|
||||
50: #de3730,
|
||||
60: #ff5449,
|
||||
70: #ff897d,
|
||||
80: #ffb4ab,
|
||||
90: #ffdad6,
|
||||
95: #ffedea,
|
||||
98: #fff8f7,
|
||||
99: #fffbff,
|
||||
100: #ffffff,
|
||||
),
|
||||
);
|
||||
|
||||
$_rest: (
|
||||
secondary: map.get($_palettes, secondary),
|
||||
neutral: map.get($_palettes, neutral),
|
||||
neutral-variant: map.get($_palettes, neutral-variant),
|
||||
error: map.get($_palettes, error),
|
||||
);
|
||||
$_primary: map.merge(map.get($_palettes, primary), $_rest);
|
||||
$_tertiary: map.merge(map.get($_palettes, tertiary), $_rest);
|
||||
|
||||
$light-theme: mat.define-theme((
|
||||
color: (
|
||||
theme-type: light,
|
||||
primary: $_primary,
|
||||
tertiary: $_tertiary,
|
||||
),
|
||||
));
|
||||
$dark-theme: mat.define-theme((
|
||||
color: (
|
||||
theme-type: dark,
|
||||
primary: $_primary,
|
||||
tertiary: $_tertiary,
|
||||
),
|
||||
));
|
||||
@@ -1,10 +1,17 @@
|
||||
@use '@angular/material' as mat;
|
||||
@use './m3-theme.scss';
|
||||
@use "@angular/material" as mat;
|
||||
@use "./theme.scss";
|
||||
|
||||
@include mat.core();
|
||||
|
||||
@mixin custom-colours($theme) {
|
||||
.mat-toolbar {
|
||||
background-color: mat.get-theme-color($theme, primary-container);
|
||||
}
|
||||
}
|
||||
|
||||
html {
|
||||
@include mat.all-component-themes(m3-theme.$dark-theme);
|
||||
@include mat.all-component-themes(theme.$rose-theme);
|
||||
@include custom-colours(theme.$rose-theme);
|
||||
}
|
||||
|
||||
html,
|
||||
|
||||
10
src/theme.scss
Normal file
10
src/theme.scss
Normal file
@@ -0,0 +1,10 @@
|
||||
@use "@angular/material" as mat;
|
||||
|
||||
$rose-theme: mat.define-theme(
|
||||
(
|
||||
color: (
|
||||
theme-type: dark,
|
||||
primary: mat.$rose-palette,
|
||||
),
|
||||
)
|
||||
);
|
||||
Reference in New Issue
Block a user