1
1
mirror of https://github.com/bitgapp/eqMac.git synced 2024-11-22 04:33:53 +03:00

moved all ui changes from Pro

This commit is contained in:
Nodeful 2021-09-28 23:43:45 +03:00
parent 05bc8e9d06
commit 2c4b037c01
16 changed files with 239 additions and 46 deletions

View File

@ -26,19 +26,13 @@
"src/favicon.ico",
"src/assets",
"src/manifest.json",
"src/robots.txt",
{
"glob": "**/*",
"input": "src/app/modules/eqmac-components/assets",
"output": "assets/"
}
"src/robots.txt"
],
"styles": [
"src/styles.scss"
],
"scripts": [],
"aot": false,
"aot": true,
"vendorChunk": true,
"extractLicenses": false,
"buildOptimizer": false,
@ -58,12 +52,11 @@
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"buildOptimizer": false,
"budgets": [
{
"type": "initial",

View File

@ -3,8 +3,8 @@
"version": "3.0.0",
"scripts": {
"lint": "npx eslint .",
"start": "ng serve --port 8080 --host 0.0.0.0 --disable-host-check",
"build": "rm -rf dist/ && ng build --configuration production && node -e \"console.log(require('./package.json').version)\" > dist/version.txt && cd dist/ && zip -r -D ui.zip * -x '*.DS_Store' && cp ui.zip ../../native/app/Embedded"
"start": "../node_modules/.bin/ng serve --port 8080 --host 0.0.0.0 --disable-host-check",
"build": "rm -rf dist/ && ../node_modules/.bin/ng build --configuration production && node -e \"console.log(require('./package.json').version)\" > dist/version.txt && cd dist/ && zip -r -D ui.zip * -x '*.DS_Store' && cp ui.zip ../../native/app/Embedded"
},
"private": true,
"dependencies": {

View File

@ -23,9 +23,9 @@
<eqm-volume-booster-balance *ngIf="ui.settings.volumeFeatureEnabled || ui.settings.balanceFeatureEnabled" #volumeBoosterBalance></eqm-volume-booster-balance>
<eqm-divider *ngIf="ui.settings.volumeFeatureEnabled || ui.settings.balanceFeatureEnabled"></eqm-divider>
<eqm-equalizers fxFlex *ngIf="ui.settings.equalizersFeatureEnabled" #equalizers></eqm-equalizers>
<eqm-divider *ngIf="ui.settings.equalizersFeatureEnabled && ui.settings.outputFeatureEnabled"></eqm-divider>
<eqm-divider *ngIf="ui.settings.equalizersFeatureEnabled"></eqm-divider>
<eqm-outputs *ngIf="ui.settings.outputFeatureEnabled" #outputs></eqm-outputs>
<eqm-tooltip-container></eqm-tooltip-container>

File diff suppressed because one or more lines are too long

View File

@ -12,6 +12,7 @@ import { TransitionService } from './services/transitions.service'
import { AnalyticsService } from './services/analytics.service'
import { ApplicationService } from './services/app.service'
import { SettingsService, IconMode } from './sections/settings/settings.service'
import { ToastService } from './services/toast.service'
import { OptionsDialogComponent } from './components/options-dialog/options-dialog.component'
import { Option, Options } from './components/options/options.component'
import { HeaderComponent } from './sections/header/header.component'
@ -59,7 +60,8 @@ export class AppComponent implements OnInit, AfterContentInit {
public transitions: TransitionService,
public analytics: AnalyticsService,
public app: ApplicationService,
public settings: SettingsService
public settings: SettingsService,
public toast: ToastService
) {
this.app.ref = this
}
@ -88,10 +90,38 @@ export class AppComponent implements OnInit, AfterContentInit {
return minHeight
}
get minWidth () {
return 400
}
get maxHeight () {
const divider = 3
const {
volumeFeatureEnabled, balanceFeatureEnabled,
equalizersFeatureEnabled,
outputFeatureEnabled
} = this.ui.settings
let maxHeight = this.header.height + divider +
((volumeFeatureEnabled || balanceFeatureEnabled) ? (this.volumeBoosterBalance.height + divider) : 0) +
(equalizersFeatureEnabled ? (this.equalizers.maxHeight + divider) : 0) +
(outputFeatureEnabled ? this.outputs.height : 0)
const dropdownSection = document.getElementById('dropdown-section')
if (dropdownSection) {
const dropdownHeight = dropdownSection.offsetHeight + this.header.height + divider
if (dropdownHeight > maxHeight) {
maxHeight = dropdownHeight
}
}
return maxHeight
}
async ngOnInit () {
await this.sync()
this.startHeightSync()
await this.fixUIMode()
this.startDimensionsSync()
await this.setupPrivacy()
}
@ -201,6 +231,7 @@ This data would help us improve and grow the product.`
async ngAfterContentInit () {
await this.utils.delay(this.animationDuration)
this.loaded = true
await this.utils.delay(1000)
this.ui.loaded()
}
@ -210,23 +241,39 @@ This data would help us improve and grow the product.`
])
}
async startHeightSync () {
this.syncHeight()
async startDimensionsSync () {
this.previousMinHeight = this.minHeight
this.previousMaxHeight = this.maxHeight
setInterval(() => {
this.syncHeight()
this.syncMinHeight()
this.syncMaxHeight()
}, 1000)
}
private previousMinHeight
async syncHeight () {
private previousMinHeight: number
async syncMinHeight () {
const diff = this.minHeight - this.previousMinHeight
this.previousMinHeight = this.minHeight
await this.ui.setMinHeight({ minHeight: this.minHeight })
if (diff !== 0) {
this.ui.onMinHeightChanged.emit()
await this.ui.setMinHeight({ minHeight: this.minHeight })
}
if (diff < 0) {
this.ui.changeHeight({ diff })
}
}
private previousMaxHeight
async syncMaxHeight () {
const diff = this.maxHeight - this.previousMaxHeight
this.previousMaxHeight = this.maxHeight
await this.ui.setMaxHeight({ maxHeight: this.maxHeight })
if (diff > 0) {
// this.ui.changeHeight({ diff })
}
}
async getTransitionSettings () {
const settings = await this.transitions.getSettings()
this.animationDuration = settings.duration
@ -239,6 +286,12 @@ This data would help us improve and grow the product.`
}
}
openDropdownSection (section: string) {
for (const key in this.showDropdownSections) {
this.showDropdownSections[key] = key === section
}
}
async fixUIMode () {
const [ mode, iconMode ] = await Promise.all([
this.ui.getMode(),
@ -250,7 +303,7 @@ This data would help us improve and grow the product.`
}
}
closeDropdownSection (section: string, event?: any) {
closeDropdownSection (section: string, event?: MouseEvent) {
// if (event && event.target && ['backdrop', 'mat-dialog'].some(e => event.target.className.includes(e))) return
if (this.dialog.openDialogs.length > 0) return
if (section in this.showDropdownSections) {

View File

@ -12,6 +12,25 @@ export interface Info {
isOpenSource: boolean
driverVersion?: string
}
export const SystemSounds = [
'Basso',
'Blow',
'Bottle',
'From',
'Funk',
'Glass',
'Hero',
'Morse',
'Ping',
'Pop',
'Purr',
'Sosumi',
'Submarine',
'Tink'
] as const
export type SystemSound = typeof SystemSounds[number]
@Injectable({
providedIn: 'root'
})
@ -85,4 +104,17 @@ export class ApplicationService extends DataService {
this.enabled = enabled
return this.request({ method: 'POST', endpoint: '/enabled', data: { enabled } })
}
async getBundleIcon (bundleId: string): Promise<string> {
const resp = await this.request({ method: 'GET', endpoint: '/bundle-icon', data: { bundleId } })
return resp?.base64
}
playAlertSound () {
return this.request({ method: 'GET', endpoint: '/alert-sound' })
}
playSystemSound (name: SystemSound) {
return this.request({ method: 'POST', endpoint: '/system-sound', data: { name } })
}
}

View File

@ -5,8 +5,8 @@ import { Injectable } from '@angular/core'
})
export class ConstantsService {
readonly DOMAIN = 'eqmac.app'
readonly FAQ_URL = new URL(`https://${this.DOMAIN}/faq`)
readonly FAQ_URL = new URL(`https://${this.DOMAIN}#faq`)
readonly FEATURES_URL = new URL(`https://${this.DOMAIN}#features`)
readonly ACCOUNT_URL = new URL(`https://${this.DOMAIN}/account`)
readonly BUG_REPORT_URL = new URL(`https://${this.DOMAIN}/report-bug`)
readonly LOCAL_API_URL = 'https://127.0.0.1'
readonly REMOTE_API_URL = `https://api.${this.DOMAIN}`
}

View File

@ -1,6 +1,6 @@
import { Injectable } from '@angular/core'
export type Context = 'EQ_TYPE_EXPERT'
export type Context = never
@Injectable({
providedIn: 'root'

View File

@ -29,7 +29,6 @@ export class ToastService {
const toast = this.snackBar.open(message, action, {
horizontalPosition: 'center',
verticalPosition: 'top',
duration,
panelClass: [ bgClass, textClass ]
})
setTimeout(() => {

View File

@ -0,0 +1,6 @@
export class Types {
static unreachable (type: never) {
console.error(`Should not have reached type: ${type}`)
}
}

View File

@ -15,7 +15,6 @@ export interface UISettings {
equalizersFeatureEnabled?: boolean
outputFeatureEnabled?: boolean
showReverbs?: boolean
showEqualizers?: boolean
reverbsShownBefore?: boolean
@ -116,6 +115,12 @@ export class UIService extends DataService {
return this.request({ method: 'POST', endpoint: '/width', data: { width } })
}
async changeWidth ({ diff }: { diff: number }) {
const currentWidth = await this.getWidth()
const width = currentWidth + diff
await this.setWidth(width)
}
async getHeight (): Promise<number> {
const { height } = await this.request({ method: 'GET', endpoint: '/height' })
return height
@ -203,6 +208,7 @@ export class UIService extends DataService {
])
}
onMinHeightChanged = new EventEmitter()
async getMinHeight (): Promise<number> {
const { minHeight } = await this.request({ method: 'GET', endpoint: '/min-height' })
return minHeight
@ -212,6 +218,33 @@ export class UIService extends DataService {
return this.request({ method: 'POST', endpoint: '/min-height', data: { minHeight } })
}
async getMinWidth (): Promise<number> {
const { minWidth } = await this.request({ method: 'GET', endpoint: '/min-width' })
return minWidth
}
async setMinWidth ({ minWidth }: { minWidth: number }) {
return this.request({ method: 'POST', endpoint: '/min-width', data: { minWidth } })
}
async getMaxHeight (): Promise<number | null> {
const { maxHeight } = await this.request({ method: 'GET', endpoint: '/max-height' })
return maxHeight
}
async setMaxHeight ({ maxHeight }: { maxHeight?: number }) {
return this.request({ method: 'POST', endpoint: '/max-height', data: { maxHeight } })
}
async getMaxWidth (): Promise<number | null> {
const { maxWidth } = await this.request({ method: 'GET', endpoint: '/max-width' })
return maxWidth
}
async setMaxWidth ({ maxWidth }: { maxWidth?: number }) {
return this.request({ method: 'POST', endpoint: '/max-width', data: { maxWidth } })
}
onShownChanged (cb: UIShownChangedEventCallback) {
this.on('/shown', cb)
}

View File

@ -12,6 +12,15 @@ export class UtilitiesService {
return (value - inMin) * (outMax - outMin) / (inMax - inMin) + outMin
}
clampValue ({ value, min, max }: { value: number, min: number, max: number }) {
if (value < min) {
value = min
} else if (value > max) {
value = max
}
return value
}
getTimestampFromDurationAndProgress (duration, progress = 1) {
const currentSecond = Math.floor(duration * progress)
let minutes = Math.floor(currentSecond / 60).toString()
@ -55,6 +64,16 @@ export class UtilitiesService {
})
}
getCoordinatesInsideElementFromEvent (event: MouseEvent, element?: HTMLElement) {
const el = element || event.target as HTMLElement
const rect = el.getBoundingClientRect()
const scale = rect.width / el.clientWidth
return {
x: (event.clientX - rect.left) / scale,
y: (event.clientY - rect.top) / scale
}
}
static async injectScript ({ src, id }: { src: string, id?: string }) {
return new Promise<void>((resolve, reject) => {
const script = document.createElement('script')
@ -74,4 +93,17 @@ export class UtilitiesService {
head.appendChild(script)
})
}
quickHash (str: string) { return UtilitiesService.quickHash(str) }
static quickHash (str: string) {
let hash = 0
let chr: number
if (str.length === 0) return hash
for (let i = 0; i < str.length; i++) {
chr = str.charCodeAt(i)
hash = ((hash << 5) - hash) + chr
hash |= 0 // Convert to 32bit integer
}
return hash
}
}

View File

@ -61,14 +61,13 @@ import 'web-animations-js' // Run `npm install --save web-animations-js`.
// (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
// (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
// (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
/*
* in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
* with the following flag, it will bypass `zone.js` patch for IE/Edge
*/
// (window as any).__Zone_enable_cross_context_check = true;
import './zone-flags'
/***************************************************************************************************
* Zone JS is required by default for Angular itself.
*/

View File

@ -2,14 +2,40 @@
@import '~@angular/cdk/overlay-prebuilt.css';
@import "~@angular/material/prebuilt-themes/pink-bluegrey.css";
.mat-dialog-container {
padding: 12px !important;
}
.w-100 {
width: 100%;
}
.h-100 {
height: 100%;
}
.mat-dialog-container {
padding: 12px !important;
}
.mat-menu-panel {
min-height: 0px !important;
}
.underline {
text-decoration: underline;
}
.clickable {
cursor: pointer !important;
* {
cursor: pointer !important;
}
}
.not-available-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(10px);
}

View File

@ -7,7 +7,7 @@
},
"angularCompilerOptions": {
"enableIvy": true,
"strictTemplates": true
"strictTemplates": true,
},
"exclude": [],
"paths": { "@angular/*": [ "./node_modules/@angular/*" ] }

2
ui/src/zone-flags.ts Normal file
View File

@ -0,0 +1,2 @@
;(window as any).__Zone_disable_requestAnimationFrame = true
;(window as any).__zone_symbol__BLACK_LISTED_EVENTS = [ 'mousewheel', 'wheel', 'mousemove', 'scroll' ] // disable patch specified eventNames