1
1
mirror of https://github.com/bitgapp/eqMac.git synced 2024-11-25 10:03:01 +03:00

made the UI work on macOS 10.12

This commit is contained in:
Nodeful 2020-10-18 19:25:41 +03:00
parent afcff2fd09
commit 6fad587780
59 changed files with 396 additions and 325 deletions

View File

@ -13,7 +13,7 @@ import AMCoreAudio
struct Constants { struct Constants {
#if DEBUG #if DEBUG
static let UI_ENDPOINT_URL = URL(string: "http://localhost:4200")! static let UI_ENDPOINT_URL = URL(string: "http://localhost:8080")!
// static let UI_ENDPOINT_URL = URL(string: "https://ui-v1.eqmac.app")! // static let UI_ENDPOINT_URL = URL(string: "https://ui-v1.eqmac.app")!
static let DEBUG = true static let DEBUG = true
#else #else

View File

@ -1048,7 +1048,7 @@
CODE_SIGN_IDENTITY = "Developer ID Application"; CODE_SIGN_IDENTITY = "Developer ID Application";
CODE_SIGN_STYLE = Manual; CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 0.3.4; CURRENT_PROJECT_VERSION = 0.3.5;
DEFINES_MODULE = YES; DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = JZA6C97KJA; DEVELOPMENT_TEAM = JZA6C97KJA;
ENABLE_HARDENED_RUNTIME = YES; ENABLE_HARDENED_RUNTIME = YES;
@ -1085,7 +1085,7 @@
"$(PROJECT_DIR)/Source/Vendor", "$(PROJECT_DIR)/Source/Vendor",
); );
MACOSX_DEPLOYMENT_TARGET = 10.12; MACOSX_DEPLOYMENT_TARGET = 10.12;
MARKETING_VERSION = v0.3.4; MARKETING_VERSION = v0.3.5;
PRODUCT_BUNDLE_IDENTIFIER = com.bitgapp.eqmac; PRODUCT_BUNDLE_IDENTIFIER = com.bitgapp.eqmac;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
@ -1109,7 +1109,7 @@
CODE_SIGN_IDENTITY = "Developer ID Application"; CODE_SIGN_IDENTITY = "Developer ID Application";
CODE_SIGN_STYLE = Manual; CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 0.3.4; CURRENT_PROJECT_VERSION = 0.3.5;
DEFINES_MODULE = YES; DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = JZA6C97KJA; DEVELOPMENT_TEAM = JZA6C97KJA;
ENABLE_HARDENED_RUNTIME = YES; ENABLE_HARDENED_RUNTIME = YES;
@ -1146,7 +1146,7 @@
"$(PROJECT_DIR)/Source/Vendor", "$(PROJECT_DIR)/Source/Vendor",
); );
MACOSX_DEPLOYMENT_TARGET = 10.12; MACOSX_DEPLOYMENT_TARGET = 10.12;
MARKETING_VERSION = v0.3.4; MARKETING_VERSION = v0.3.5;
PRODUCT_BUNDLE_IDENTIFIER = com.bitgapp.eqmac; PRODUCT_BUNDLE_IDENTIFIER = com.bitgapp.eqmac;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";

View File

@ -0,0 +1,6 @@
You will be guided through the steps necessary to install eqMac.
⚠️ WARNING ⚠️
If the Installer will need to install/update the Audio Driver (required for eqMac to work correctly), by the end of the installation:
YOU MIGHT BE LOGGED OUT OF YOUR CURRENT USER SESSION
so please save any work progress you might have!

View File

@ -13,61 +13,76 @@ if [ "$CURRENT_DRIVER_VERSION" != "$NEEDED_DRIVER_VERSION" ]; then
# Copy driver into Plug-Ins folder # Copy driver into Plug-Ins folder
cp -f -r "$DIR/eqMac.driver" /Library/Audio/Plug-Ins/HAL/ &>/dev/null cp -f -r "$DIR/eqMac.driver" /Library/Audio/Plug-Ins/HAL/ &>/dev/null
if osascript <<EOT # Restart CoreAudio
tell application id "com.apple.systemuiserver" coreaudiod_plist="/System/Library/LaunchDaemons/com.apple.audio.coreaudiod.plist"
display dialog \ (launchctl kickstart -k system/com.apple.audio.coreaudiod &>/dev/null || \
"It is recommended you restart your Mac for the eqMac Audio Driver to function properly." \ launchctl kill SIGTERM system/com.apple.audio.coreaudiod &>/dev/null || \
buttons {"Skip restart", "Restart Mac"} \ launchctl kill TERM system/com.apple.audio.coreaudiod &>/dev/null || \
default button "Restart Mac" \ launchctl kill 15 system/com.apple.audio.coreaudiod &>/dev/null || \
cancel button "Skip restart" \ launchctl kill -15 system/com.apple.audio.coreaudiod &>/dev/null || \
with icon POSIX file "/Applications/eqMac.app/Contents/Resources/AppIcon.icns" (launchctl unload "$coreaudiod_plist" &>/dev/null && \
end tell launchctl load "$coreaudiod_plist" &>/dev/null) || \
EOT killall coreaudiod &>/dev/null)
then
echo "RESTART" # Logout
open /Applications/eqMac.app pkill loginwindow
# if osascript <<EOT
# tell application id "com.apple.systemuiserver"
# display dialog \
# "It is recommended you restart your Mac for the eqMac Audio Driver to function properly." \
# buttons {"Skip restart", "Restart Mac"} \
# default button "Restart Mac" \
# cancel button "Skip restart" \
# with icon POSIX file "/Applications/eqMac.app/Contents/Resources/AppIcon.icns"
# end tell
# EOT
# then
# echo "RESTART"
osascript <<EOT # osascript <<EOT
ignoring application responses # ignoring application responses
tell application "System Events" to restart # tell application "System Events" to restart
end ignoring # end ignoring
EOT # EOT
pkill -9 "Installer" # pkill -9 "Installer"
exit 0 # exit 0
else # else
echo "SKIP RESTART" # echo "SKIP RESTART"
# Restart CoreAudio # # Restart CoreAudio
coreaudiod_plist="/System/Library/LaunchDaemons/com.apple.audio.coreaudiod.plist" # coreaudiod_plist="/System/Library/LaunchDaemons/com.apple.audio.coreaudiod.plist"
(launchctl kickstart -k system/com.apple.audio.coreaudiod &>/dev/null || \ # (launchctl kickstart -k system/com.apple.audio.coreaudiod &>/dev/null || \
launchctl kill SIGTERM system/com.apple.audio.coreaudiod &>/dev/null || \ # launchctl kill SIGTERM system/com.apple.audio.coreaudiod &>/dev/null || \
launchctl kill TERM system/com.apple.audio.coreaudiod &>/dev/null || \ # launchctl kill TERM system/com.apple.audio.coreaudiod &>/dev/null || \
launchctl kill 15 system/com.apple.audio.coreaudiod &>/dev/null || \ # launchctl kill 15 system/com.apple.audio.coreaudiod &>/dev/null || \
launchctl kill -15 system/com.apple.audio.coreaudiod &>/dev/null || \ # launchctl kill -15 system/com.apple.audio.coreaudiod &>/dev/null || \
(launchctl unload "$coreaudiod_plist" &>/dev/null && \ # (launchctl unload "$coreaudiod_plist" &>/dev/null && \
launchctl load "$coreaudiod_plist" &>/dev/null) || \ # launchctl load "$coreaudiod_plist" &>/dev/null) || \
killall coreaudiod &>/dev/null) && \ # killall coreaudiod &>/dev/null)
sleep 5
# Wait until coreaudiod has restarted and device is ready to use. # # Wait until CoreAudio restarts
retries=5 # sleep 5
while [[ $retries -gt 0 ]]; do
if ! system_profiler SPAudioDataType | grep "eqMac:" >/dev/null 2>&1; then
retries=$((retries - 1))
if [[ $retries -gt 0 ]]; then
echo "Device not ready yet, waiting..."
sleep 3
else
echo "ERROR: Device did not become active"
exit 1
fi
else
retries=0
fi
done
echo "Device became active"
open /Applications/eqMac.app # # Wait until coreaudiod has restarted and device is ready to use.
fi # retries=5
# while [[ $retries -gt 0 ]]; do
# if ! system_profiler SPAudioDataType | grep "eqMac:" >/dev/null 2>&1; then
# retries=$((retries - 1))
# if [[ $retries -gt 0 ]]; then
# echo "Device not ready yet, waiting..."
# sleep 3
# else
# echo "ERROR: Device did not become active"
# exit 1
# fi
# else
# retries=0
# fi
# done
# echo "Device became active"
# fi
fi fi
open /Applications/eqMac.app

View File

@ -4,5 +4,7 @@ last 2 versions
Firefox ESR Firefox ESR
safari 12.1 safari 12.1
safari 12 safari 12
safari 10.1
safari 10
not dead not dead
# IE 9-11 # IE 9-11

View File

@ -8,7 +8,7 @@
"name": "Launch Client", "name": "Launch Client",
"type": "chrome", "type": "chrome",
"request": "launch", "request": "launch",
"url": "http://localhost:4200/#", "url": "http://localhost:8080/#",
"port": 9223, "port": 9223,
"sourceMaps": true, "sourceMaps": true,
"diagnosticLogging": true, "diagnosticLogging": true,
@ -24,7 +24,7 @@
"type": "chrome", "type": "chrome",
"request": "attach", "request": "attach",
"port": 9000, "port": 9000,
"url": "http://localhost:4200/#", "url": "http://localhost:8080/#",
"webRoot": "${workspaceRoot}/src" "webRoot": "${workspaceRoot}/src"
}, { }, {
"name": "Deploy (production)", "name": "Deploy (production)",

12
ui/package-lock.json generated
View File

@ -1,6 +1,6 @@
{ {
"name": "eqmac", "name": "eqmac",
"version": "1.2.0", "version": "1.2.1",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
@ -2354,6 +2354,11 @@
"@xtuc/long": "4.2.2" "@xtuc/long": "4.2.2"
} }
}, },
"@webcomponents/custom-elements": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/@webcomponents/custom-elements/-/custom-elements-1.4.2.tgz",
"integrity": "sha512-bLw2XH9+2NBwmn7BI6WA2oIo2eOfBpl+GjAqkF/qnkZ8kq3HY5tKYTxtKowWALAferTp3wKD8W6FSn5OyK+rtQ=="
},
"@xtuc/ieee754": { "@xtuc/ieee754": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
@ -10637,6 +10642,11 @@
"minimalistic-assert": "^1.0.0" "minimalistic-assert": "^1.0.0"
} }
}, },
"web-animations-js": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/web-animations-js/-/web-animations-js-2.3.2.tgz",
"integrity": "sha512-TOMFWtQdxzjWp8qx4DAraTWTsdhxVSiWa6NkPFSaPtZ1diKUxTn4yTix73A1euG1WbSOMMPcY51cnjTIHrGtDA=="
},
"webpack": { "webpack": {
"version": "4.39.2", "version": "4.39.2",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-4.39.2.tgz", "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.39.2.tgz",

View File

@ -2,7 +2,7 @@
"name": "eqmac", "name": "eqmac",
"version": "1.2.1", "version": "1.2.1",
"scripts": { "scripts": {
"start": "ng serve", "start": "ng serve --port 8080",
"build": "rm -rf dist/ && ng build --prod && cd dist/ && zip -r -D ui.zip * -x '*.DS_Store' && cp ui.zip ../../native/app/Embedded", "build": "rm -rf dist/ && ng build --prod && cd dist/ && zip -r -D ui.zip * -x '*.DS_Store' && cp ui.zip ../../native/app/Embedded",
"deploy": "export $(egrep -v '^#' .env | xargs) && ./scripts/deploy.sh", "deploy": "export $(egrep -v '^#' .env | xargs) && ./scripts/deploy.sh",
"purge-cache": "./node_modules/.bin/ts-node -O '{\"module\":\"commonjs\"}' ./scripts/purge-cache.ts" "purge-cache": "./node_modules/.bin/ts-node -O '{\"module\":\"commonjs\"}' ./scripts/purge-cache.ts"
@ -22,11 +22,13 @@
"@angular/pwa": "^0.803.8", "@angular/pwa": "^0.803.8",
"@angular/router": "~8.2.9", "@angular/router": "~8.2.9",
"@angular/service-worker": "~8.2.9", "@angular/service-worker": "~8.2.9",
"@webcomponents/custom-elements": "^1.4.2",
"core-js": "^3.2.1", "core-js": "^3.2.1",
"js-cookie": "^2.2.1", "js-cookie": "^2.2.1",
"ng-click-outside": "^5.1.1", "ng-click-outside": "^5.1.1",
"rxjs": "~6.5.3", "rxjs": "~6.5.3",
"ui-carousel": "^0.2.0", "ui-carousel": "^0.2.0",
"web-animations-js": "^2.3.2",
"zone.js": "~0.10.2" "zone.js": "~0.10.2"
}, },
"devDependencies": { "devDependencies": {

View File

@ -32,13 +32,13 @@ export class AppComponent implements OnInit, AfterContentInit {
} }
constructor ( constructor (
private utils: UtilitiesService, public utils: UtilitiesService,
private ui: UIService, public ui: UIService,
public matDialog: MatDialog, public matDialog: MatDialog,
private transitions: TransitionService, public transitions: TransitionService,
private analytics: AnalyticsService, public analytics: AnalyticsService,
private app: ApplicationService, public app: ApplicationService,
private settings: SettingsService public settings: SettingsService
) { } ) { }
async ngOnInit () { async ngOnInit () {

View File

@ -1,6 +1,6 @@
<div fxLayout="column" fxLayoutAlign="space-around start" fxLayoutGap="10px"> <div fxLayout="column" fxLayoutAlign="space-around start" fxLayoutGap="10px">
<div *ngFor="let row of options" fxLayout="row" fxFill fxLayoutGap="10px" fxLayoutAlign="space-between center"> <div *ngFor="let row of options" fxLayout="row" style="width: 100%" fxLayoutGap="10px" fxLayoutAlign="space-between center">
<div *ngFor="let option of row" [fxFlex]="100 / row.length" [style.width.%]="option.type === 'button' ? 100 : undefined"> <div *ngFor="let option of row" [fxFlex]="100 / row.length" [ngStyle]="getOptionStyle(option.type)">
<div *ngIf="option.type === 'checkbox'" <div *ngIf="option.type === 'checkbox'"
fxLayout="row" fxLayoutAlign="center center" fxFill fxLayoutGap="10px" fxLayout="row" fxLayoutAlign="center center" fxFill fxLayoutGap="10px"
(click)="toggleCheckbox(option)"> (click)="toggleCheckbox(option)">

View File

@ -41,7 +41,16 @@ export class OptionsComponent {
@Input() options: Options = [] @Input() options: Options = []
@Output() checkboxToggled = new EventEmitter<CheckboxOption>() @Output() checkboxToggled = new EventEmitter<CheckboxOption>()
constructor (private ref: ChangeDetectorRef) {} constructor (public ref: ChangeDetectorRef) {}
getOptionStyle (type: Option['type']) {
let style: any = {}
if (type === 'button') {
style.width = '100%'
}
return style
}
toggleCheckbox (checkbox: CheckboxOption) { toggleCheckbox (checkbox: CheckboxOption) {
checkbox.value = !checkbox.value checkbox.value = !checkbox.value

View File

@ -16,14 +16,14 @@ export class AnalyzerComponent implements OnInit {
@ViewChild('container', { @ViewChild('container', {
read: ElementRef, read: ElementRef,
static: true static: true
}) container }) container
height = 0 height = 0
width = 0 width = 0
halfHeight = 0 halfHeight = 0
halfWidth = 0 halfWidth = 0
constructor (private elRef: ElementRef) {} constructor (public elRef: ElementRef) {}
ngOnInit () { ngOnInit () {
} }

View File

@ -1,3 +1,3 @@
<div (click)="click()" [class]="computeClass()" [style.height.px]="height" [style.width.px]="width"> <div (click)="click()" [class]="computeClass()" [ngStyle]="style">
<ng-content></ng-content> <ng-content></ng-content>
</div> </div>

View File

@ -20,6 +20,13 @@ export class ButtonComponent implements OnInit {
ngOnInit () { ngOnInit () {
} }
get style () {
return {
width: `${this.width}px`,
height: `${this.height}px`
}
}
computeClass () { computeClass () {
let className = 'button' let className = 'button'
className += ` ${this.type}` className += ` ${this.type}`

View File

@ -1,3 +1,3 @@
<div class="wrapper" [style.height.px]="height" [style.transition-duration.ms]="animationDuration" #wrapper [style.width.%]="items.length * 100"> <div class="wrapper" [ngStyle]="wrapperStyle" #wrapper>
<ng-container *ngFor="let item of items;" class="item" [ngTemplateOutlet]="item.template"></ng-container> <ng-container *ngFor="let item of items;" class="item" [ngTemplateOutlet]="item.template"></ng-container>
</div> </div>

View File

@ -43,9 +43,9 @@ export class CarouselComponent implements AfterViewInit, OnDestroy {
} }
@Output() heightDiff = new EventEmitter<number>() @Output() heightDiff = new EventEmitter<number>()
@Output() heightChange = new EventEmitter<number>() @Output() heightChange = new EventEmitter<number>()
private recalculateHeightTimer public recalculateHeightTimer
private _selectedItemId: string public _selectedItemId: string
@Input() set selectedItemId (newSelectedItemId: string) { @Input() set selectedItemId (newSelectedItemId: string) {
if (this._selectedItemId !== newSelectedItemId) { if (this._selectedItemId !== newSelectedItemId) {
this._selectedItemId = newSelectedItemId this._selectedItemId = newSelectedItemId
@ -60,10 +60,18 @@ export class CarouselComponent implements AfterViewInit, OnDestroy {
@Output() itemCameIntoView = new EventEmitter<string>() @Output() itemCameIntoView = new EventEmitter<string>()
constructor ( constructor (
private builder: AnimationBuilder public builder: AnimationBuilder
) { ) {
} }
get wrapperStyle () {
return {
height: `${this.height}px`,
transitionDuration: `${this.animationDuration}ms`,
width: `${this.items.length * 100}%`
}
}
ngAfterViewInit () { ngAfterViewInit () {
for (const item of this.items.toArray()) { for (const item of this.items.toArray()) {
if (!item.eqmCarouselItem || typeof item.eqmCarouselItem !== 'string') { if (!item.eqmCarouselItem || typeof item.eqmCarouselItem !== 'string') {
@ -104,21 +112,21 @@ export class CarouselComponent implements AfterViewInit, OnDestroy {
this.selectedItemIdChange.emit(this.selectedItemId) this.selectedItemIdChange.emit(this.selectedItemId)
} }
private animate () { public animate () {
const myAnimation: AnimationFactory = this.animation const myAnimation: AnimationFactory = this.animation
const player = myAnimation.create(this.wrapper.nativeElement) const player = myAnimation.create(this.wrapper.nativeElement)
player.play() player.play()
setTimeout(() => this.animationCompleted.emit(), this.animationDuration) setTimeout(() => this.animationCompleted.emit(), this.animationDuration)
} }
private get animation () { public get animation () {
const offset = this.currentIndex * 100 / this.items.length const offset = this.currentIndex * 100 / this.items.length
return this.builder.build([ return this.builder.build([
animate(`${this.animationDuration}ms ease-in`, style({ transform: `translateX(-${offset}%)` })) animate(`${this.animationDuration}ms ease-in`, style({ transform: `translateX(-${offset}%)` }))
]) ])
} }
private recalculateHeight () { public recalculateHeight () {
const itemEl = this.itemElems && this.itemElems.toArray()[this.currentIndex].nativeElement.nextElementSibling const itemEl = this.itemElems && this.itemElems.toArray()[this.currentIndex].nativeElement.nextElementSibling
itemEl && itemEl.offsetHeight && (this.height = itemEl.offsetHeight) itemEl && itemEl.offsetHeight && (this.height = itemEl.offsetHeight)
} }

View File

@ -1 +0,0 @@
<div [class]="'divider ' + (_horizontal ? 'horizontal' : 'vertical')"></div>

View File

@ -1,16 +1,5 @@
.divider { :host {
display: block;
overflow: hidden;
background-color: black; background-color: black;
} }
.horizontal {
width: 100%;
height: 1px;
border-top: 1px solid rgb(58, 59, 61);
border-bottom: 1px solid rgb(96, 97, 101);
}
.vertical {
height: 100%;
width: 1px;
border-left: 1px solid rgb(58, 59, 61);
border-right: 1px solid rgb(96, 97, 101);
}

View File

@ -1,27 +1,45 @@
import { Component, OnInit, Input, ElementRef } from '@angular/core' import { Component, OnInit, Input, ElementRef, HostBinding } from '@angular/core'
@Component({ @Component({
selector: 'eqm-divider', selector: 'eqm-divider',
templateUrl: './divider.component.html', templateUrl: './divider.component.html',
styleUrls: ['./divider.component.scss'] styleUrls: ['./divider.component.scss']
}) })
export class DividerComponent implements OnInit { export class DividerComponent {
@Input() orientation: 'vertical' | 'horizontal' = 'horizontal'
constructor (private elRef: ElementRef) { } constructor (
_horizontal = true public elem: ElementRef
_vertical = false ) {}
@Input()
set horizontal (isHorizontal) { @HostBinding('style.width')
this._horizontal = isHorizontal get width () {
this._vertical = !isHorizontal return this.orientation === 'vertical' ? '1px' : `${this.elem.nativeElement.parentElement.offsetWidth}`
} }
@Input() @HostBinding('style.height')
set vertical (isVertical) { get height () {
this._vertical = isVertical return this.orientation === 'vertical' ? `${this.elem.nativeElement.parentElement.offsetHeight}` : '1px'
this._horizontal = !isVertical
} }
ngOnInit () {
@HostBinding('style.border-left')
get leftBorder () {
return this.orientation === 'vertical' ? '1px solid rgb(58, 59, 61)' : undefined
}
@HostBinding('style.border-right')
get rightBorder () {
return this.orientation === 'vertical' ? '1px solid rgb(96, 97, 101)' : undefined
}
@HostBinding('style.border-top')
get topBorder () {
return this.orientation === 'horizontal' ? '1px solid rgb(58, 59, 61)' : undefined
}
@HostBinding('style.border-bottom')
get bottomtBorder () {
return this.orientation === 'horizontal' ? '1px solid rgb(96, 97, 101)' : undefined
} }
} }

View File

@ -7,15 +7,6 @@
transition-duration: 0.5s; transition-duration: 0.5s;
} }
.arrows {
width: 20px;
display: inline-flex;
flex-direction: column;
text-align: center;
position: absolute;
right: 0px;
}
.container { .container {
z-index: 3; z-index: 3;
width: 100%; width: 100%;
@ -28,6 +19,16 @@
transform: translateX(-2px); transform: translateX(-2px);
} }
.arrows {
width: 20px;
display: inline-flex;
flex-direction: column;
text-align: center;
position: absolute;
right: 0px;
top: calc(50% - 16px/2);
}
$animation-duration: .2s; $animation-duration: .2s;
.items-select-box{ .items-select-box{

View File

@ -11,8 +11,8 @@ import { FadeInOutAnimation } from 'src/app/modules/animations'
animations: [ FadeInOutAnimation ] animations: [ FadeInOutAnimation ]
}) })
export class DropdownComponent implements OnInit { export class DropdownComponent implements OnInit {
constructor (private utils: UtilitiesService, private zone: NgZone) { } constructor (public utils: UtilitiesService, public zone: NgZone) { }
private _items: any[] = [] public _items: any[] = []
hasSelection = false hasSelection = false
@Input() editable = false @Input() editable = false
@Input() @Input()
@ -40,7 +40,7 @@ export class DropdownComponent implements OnInit {
shown = false shown = false
yCoordinate = 0 yCoordinate = 0
direction: 'down' | 'up' = 'down' direction: 'down' | 'up' = 'down'
private padding = 5 public padding = 5
async ngOnInit () { async ngOnInit () {
if (!this.items) this.items = [] if (!this.items) this.items = []

View File

@ -1,4 +1,7 @@
<div class="groove" [ngStyle]="grooveStyle"></div>
<div class="groove-filling" [ngStyle]="grooveFillingStyle"></div> <div class="container" #container [ngStyle]="containerStyle">
<div class="thumbNotch" [ngStyle]="thumbNotchStyle"></div> <div class="groove" [ngStyle]="grooveStyle"></div>
<div class="thumb" [ngStyle]="thumbStyle" (dblclick)="doubleclick()"></div> <div class="groove-filling" [ngStyle]="grooveFillingStyle"></div>
<div class="thumbNotch" [ngStyle]="thumbNotchStyle"></div>
<div class="thumb" [ngStyle]="thumbStyle" (dblclick)="doubleclick()"></div>
</div>

View File

@ -1,24 +1,18 @@
:host { :host {
position: relative; display: block;
display: flex; padding: 2px;
align-items: center;
justify-content: center;
} }
:host.disabled { :host.disabled {
filter: grayscale(80%); filter: grayscale(80%);
} }
.container {
position: relative;
.groove { * {
position: absolute; position: absolute;
}
} }
.groove-filling {
position: absolute;
}
.thumb {
position: absolute;
}

View File

@ -28,9 +28,9 @@ export interface FlatSliderValueChangedEvent {
}) })
export class FlatSliderComponent { export class FlatSliderComponent {
constructor ( constructor (
private utils: UtilitiesService, public utils: UtilitiesService,
private elem: ElementRef, public elem: ElementRef,
private sanitizer: DomSanitizer public sanitizer: DomSanitizer
) {} ) {}
@Input() doubleClickToAnimateToMiddle = true @Input() doubleClickToAnimateToMiddle = true
@ -44,12 +44,14 @@ export class FlatSliderComponent {
@Input() thickness = 2 @Input() thickness = 2
@Input() orientation: 'vertical' | 'horizontal' = 'horizontal' @Input() orientation: 'vertical' | 'horizontal' = 'horizontal'
@Output() stickedToMiddle = new EventEmitter() @Output() stickedToMiddle = new EventEmitter()
@ViewChild('container', { static: true }) containerRef: ElementRef
get middleValue () { get middleValue () {
return typeof this.middle === 'number' ? this.middle : (this.min + this.max) / 2 return typeof this.middle === 'number' ? this.middle : (this.min + this.max) / 2
} }
private defaultColor = '#4f8d71' public defaultColor = '#4f8d71'
private _enabled = true public _enabled = true
@HostBinding('class.disabled') get disabled () { return !this.enabled } @HostBinding('class.disabled') get disabled () { return !this.enabled }
@Input() @Input()
@ -59,7 +61,7 @@ export class FlatSliderComponent {
} }
get enabled () { return this._enabled } get enabled () { return this._enabled }
private _color = this.defaultColor public _color = this.defaultColor
@Input() @Input()
set color (newColor) { set color (newColor) {
this.defaultColor = newColor this.defaultColor = newColor
@ -78,10 +80,10 @@ export class FlatSliderComponent {
return hex return hex
} }
private dragging = false public dragging = false
private knobRadius = 4 public knobRadius = 4
private _value = .5 public _value = .5
@Input() @Input()
set value (newValue) { set value (newValue) {
let value = this.clampValue(newValue) let value = this.clampValue(newValue)
@ -112,13 +114,13 @@ export class FlatSliderComponent {
@Output() userChangedValue = new EventEmitter<FlatSliderValueChangedEvent>() @Output() userChangedValue = new EventEmitter<FlatSliderValueChangedEvent>()
get height () { get height () {
return this.elem.nativeElement.offsetHeight return this.containerRef.nativeElement.offsetHeight
} }
get width () { get width () {
return this.elem.nativeElement.offsetWidth return this.containerRef.nativeElement.offsetWidth
} }
private clampValue (value) { public clampValue (value) {
if (value < this.min) return this.min if (value < this.min) return this.min
if (value > this.max) return this.max if (value > this.max) return this.max
return value return value
@ -133,7 +135,7 @@ export class FlatSliderComponent {
} }
} }
private getValueFromMouseEvent (event: MouseEvent) { public getValueFromMouseEvent (event: MouseEvent) {
const coords = this.utils.getCoordinatesInsideElementFromEvent(event, this.elem.nativeElement) const coords = this.utils.getCoordinatesInsideElementFromEvent(event, this.elem.nativeElement)
const progress = this.orientation === 'vertical' ? coords.y : coords.x const progress = this.orientation === 'vertical' ? coords.y : coords.x
const value = this.utils.mapValue(progress, this.knobRadius, (this.orientation === 'vertical' ? this.height : this.width) - this.knobRadius, this.min, this.max) const value = this.utils.mapValue(progress, this.knobRadius, (this.orientation === 'vertical' ? this.height : this.width) - this.knobRadius, this.min, this.max)
@ -157,7 +159,7 @@ export class FlatSliderComponent {
} }
} }
private mouseInside = false public mouseInside = false
@HostListener('mouseenter') @HostListener('mouseenter')
onMouseEnter (): void { onMouseEnter (): void {
this.mouseInside = true this.mouseInside = true
@ -168,7 +170,7 @@ export class FlatSliderComponent {
this.dragging = false this.dragging = false
} }
private doubleclickTimeout = null public doubleclickTimeout = null
doubleclick () { doubleclick () {
if (this.enabled && this.doubleClickToAnimateToMiddle) { if (this.enabled && this.doubleClickToAnimateToMiddle) {
if (this.doubleclickTimeout) { if (this.doubleclickTimeout) {
@ -211,34 +213,30 @@ export class FlatSliderComponent {
return this.utils.mapValue(this.value, this.min, this.max, 0, 1) return this.utils.mapValue(this.value, this.min, this.max, 0, 1)
} }
@HostBinding('style') get containerStyle () {
get style (): SafeStyle {
const styles: { [style: string]: string } = {} const styles: { [style: string]: string } = {}
const thickness = this.knobRadius * 2 + 2 const height = this.knobRadius * 2 + 2
if (this.orientation === 'horizontal') { if (this.orientation === 'horizontal') {
styles.width = `100%` styles.width = `100%`
styles.height = `${thickness}px` styles.height = `${height}px`
styles.flexDirection = 'column'
} else { } else {
styles.height = `100%` styles.height = `100%`
styles.width = `${thickness}px` styles.width = `${height}px`
styles.flexDirection = 'row'
} }
const style = Object.entries(styles) return styles
.map(([ key, value ]) => `${key}: ${value}`)
.join('; ')
return this.sanitizer.bypassSecurityTrustStyle(style)
} }
get grooveStyle () { get grooveStyle () {
const style: { [style: string]: string | number } = {} const style: { [style: string]: string | number } = {}
if (this.orientation === 'horizontal') { if (this.orientation === 'horizontal') {
style.left = `${this.knobRadius}px` style.left = `${this.knobRadius}px`
style.top = `calc(50% - ${this.thickness}px / 2)`
style.width = `calc(100% - ${this.knobRadius * 2}px)` style.width = `calc(100% - ${this.knobRadius * 2}px)`
style.height = `${this.thickness}px` style.height = `${this.thickness}px`
} else { } else {
style.bottom = `${this.knobRadius}px` style.top = `${this.knobRadius}px`
style.left = `calc(50% - ${this.thickness}px / 2)`
style.height = `calc(100% - ${this.knobRadius * 2}px)` style.height = `calc(100% - ${this.knobRadius * 2}px)`
style.width = `${this.thickness}px` style.width = `${this.thickness}px`
} }
@ -250,10 +248,12 @@ export class FlatSliderComponent {
const style: { [style: string]: string } = {} const style: { [style: string]: string } = {}
if (this.orientation === 'horizontal') { if (this.orientation === 'horizontal') {
style.left = `${this.knobRadius}px` style.left = `${this.knobRadius}px`
style.top = `calc(50% - ${this.thickness}px / 2)`
style.width = `calc(${this.progress * 100}% - ${this.knobRadius}px)` style.width = `calc(${this.progress * 100}% - ${this.knobRadius}px)`
style.height = `${this.thickness}px` style.height = `${this.thickness}px`
} else { } else {
style.bottom = `${this.knobRadius}px` style.top = `${this.knobRadius}px`
style.left = `calc(50% - ${this.thickness}px / 2)`
style.height = `calc(${this.progress * 100}% - ${this.knobRadius * 2}px)` style.height = `calc(${this.progress * 100}% - ${this.knobRadius * 2}px)`
style.width = `${this.thickness}px` style.width = `${this.thickness}px`
} }
@ -268,11 +268,9 @@ export class FlatSliderComponent {
style.backgroundColor = this.value >= this.middleValue ? this.color : this.darkerColor style.backgroundColor = this.value >= this.middleValue ? this.color : this.darkerColor
style.borderRadius = '100%' style.borderRadius = '100%'
if (this.orientation === 'horizontal') { const center = `calc(50% - ${this.knobRadius}px)`
style.left = `${this.utils.mapValue(this.middleValue, this.min, this.max, 0, this.width)}px` style.left = center
} else { style.top = center
style.bottom = `${this.utils.mapValue(this.middleValue, this.min, this.max, 0, this.height)}px`
}
return style return style
} }

View File

@ -42,7 +42,7 @@ export class IconComponent implements OnInit {
} }
} }
private _rotate = 0 public _rotate = 0
@Input() @Input()
get rotate () { get rotate () {
return this._rotate return this._rotate
@ -61,7 +61,7 @@ export class IconComponent implements OnInit {
@Input() stroke: number = 0 @Input() stroke: number = 0
constructor (private sanitizer: DomSanitizer) {} constructor (public sanitizer: DomSanitizer) {}
ngOnInit () { ngOnInit () {
} }

View File

@ -38,7 +38,7 @@
</clipPath> </clipPath>
</defs> </defs>
</svg> </svg>
<div class="cap-body" [ngStyle]="largeCapBodyStyle"></div> <!-- <div class="cap-body" [ngStyle]="largeCapBodyStyle"></div> -->
<div class="indicator" [ngStyle]="largeCapIndicatorStyle"> <div class="indicator" [ngStyle]="largeCapIndicatorStyle">
<svg class="inner-line" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" <svg class="inner-line" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" width="40px" height="40px" viewBox="0 0 40 40" style="enable-background:new 0 0 40 40;" y="0px" width="40px" height="40px" viewBox="0 0 40 40" style="enable-background:new 0 0 40 40;"

View File

@ -25,11 +25,11 @@ export class KnobComponent implements OnInit {
@Input() size: 'large' | 'medium' | 'small' = 'medium' @Input() size: 'large' | 'medium' | 'small' = 'medium'
@Input() showScale = true @Input() showScale = true
id = uuid() id = uuid()
private _min = -1 public _min = -1
@Input() set min (newMin) { this._min = newMin; this.calculateMiddleValue() } @Input() set min (newMin) { this._min = newMin; this.calculateMiddleValue() }
get min () { return this._min } get min () { return this._min }
private _max = 1 public _max = 1
@Input() set max (newMax) { this._max = newMax; this.calculateMiddleValue() } @Input() set max (newMax) { this._max = newMax; this.calculateMiddleValue() }
get max () { return this._max } get max () { return this._max }
@ -43,15 +43,15 @@ export class KnobComponent implements OnInit {
@Input() stickToMiddle = false @Input() stickToMiddle = false
@Output() stickedToMiddle = new EventEmitter() @Output() stickedToMiddle = new EventEmitter()
private dragging = false public dragging = false
private setDraggingFalseTimeout: any = null public setDraggingFalseTimeout: any = null
private continueAnimation = false public continueAnimation = false
private dragStartDegr = 0 public dragStartDegr = 0
@ViewChild('container', { static: true }) containerRef: ElementRef @ViewChild('container', { static: true }) containerRef: ElementRef
container: HTMLDivElement container: HTMLDivElement
private _value = 0 public _value = 0
@Output() valueChange = new EventEmitter<number>() @Output() valueChange = new EventEmitter<number>()
@Output() userChangedValue = new EventEmitter<KnobValueChangedEvent>() @Output() userChangedValue = new EventEmitter<KnobValueChangedEvent>()
@Input() @Input()
@ -82,12 +82,12 @@ export class KnobComponent implements OnInit {
} }
middleValue: number = this.calculateMiddleValue() middleValue: number = this.calculateMiddleValue()
private calculateMiddleValue () { public calculateMiddleValue () {
this.middleValue = (this.min + this.max) / 2 this.middleValue = (this.min + this.max) / 2
return this.middleValue return this.middleValue
} }
constructor (private utils: UtilitiesService) {} constructor (public utils: UtilitiesService) {}
async ngOnInit () { async ngOnInit () {
this.container = this.containerRef.nativeElement this.container = this.containerRef.nativeElement
@ -239,7 +239,7 @@ export class KnobComponent implements OnInit {
return return
} }
private getDegreesFromEvent (event) { public getDegreesFromEvent (event) {
const coords = this.utils.getCoordinatesInsideElementFromEvent(event, this.container) const coords = this.utils.getCoordinatesInsideElementFromEvent(event, this.container)
const knobCenterX = (this.container.clientWidth) / 2 const knobCenterX = (this.container.clientWidth) / 2
const knobCenterY = (this.container.clientHeight) / 2 const knobCenterY = (this.container.clientHeight) / 2
@ -247,7 +247,7 @@ export class KnobComponent implements OnInit {
return rads * 100 return rads * 100
} }
private getDistanceFromCenterOfElementAndEvent (event) { public getDistanceFromCenterOfElementAndEvent (event) {
const coords = this.utils.getCoordinatesInsideElementFromEvent(event, this.container) const coords = this.utils.getCoordinatesInsideElementFromEvent(event, this.container)
const knobCenterX = (this.container.clientWidth) / 2 const knobCenterX = (this.container.clientWidth) / 2
const knobCenterY = (this.container.clientHeight) / 2 const knobCenterY = (this.container.clientHeight) / 2
@ -256,7 +256,7 @@ export class KnobComponent implements OnInit {
return Math.sqrt(w * w + h * h) return Math.sqrt(w * w + h * h)
} }
private clampValue (value) { public clampValue (value) {
if (value > this.max) { if (value > this.max) {
value = this.max value = this.max
} }

View File

@ -21,7 +21,7 @@ export class SelectBoxComponent implements OnInit {
@Input() selectedItem = null @Input() selectedItem = null
@Output() itemSelected = new EventEmitter() @Output() itemSelected = new EventEmitter()
@ViewChild('container', { read: ElementRef, static: true }) container @ViewChild('container', { read: ElementRef, static: true }) container
private _nVisibleItems: number = 6 public _nVisibleItems: number = 6
@Input() @Input()
set numberOfVisibleItems (value: number) { set numberOfVisibleItems (value: number) {
if (!isNaN(parseInt(value.toString(), 10))) { if (!isNaN(parseInt(value.toString(), 10))) {
@ -39,24 +39,24 @@ export class SelectBoxComponent implements OnInit {
hidden = true hidden = true
itemHeight = 25 itemHeight = 25
constructor (private host: ElementRef) { } constructor (public host: ElementRef) { }
ngOnInit () { ngOnInit () {
this.setDimensions() this.setDimensions()
} }
private setDimensions () { public setDimensions () {
this.setHeight() this.setHeight()
this.setWidth() this.setWidth()
} }
private setHeight () { public setHeight () {
const lowest = Math.min(this._nVisibleItems, this.items.length) const lowest = Math.min(this._nVisibleItems, this.items.length)
this.height = lowest * this.itemHeight + (this.numberOfVisibleItems < this.items.length ? this.itemHeight / 2 : 0) this.height = lowest * this.itemHeight + (this.numberOfVisibleItems < this.items.length ? this.itemHeight / 2 : 0)
this.host.nativeElement.style.height = `${this.height}px` this.host.nativeElement.style.height = `${this.height}px`
} }
private setWidth () { public setWidth () {
if (this.width) { if (this.width) {
this.host.nativeElement.style.height = `${this.height}px` this.host.nativeElement.style.height = `${this.height}px`
} }

View File

@ -11,6 +11,14 @@
transition-duration: .5s; transition-duration: .5s;
} }
.notches {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
}
.groove { .groove {
width: 7px; width: 7px;
height: 89%; height: 89%;
@ -29,6 +37,7 @@
justify-content: center; justify-content: center;
align-items: center; align-items: center;
top: 0; top: 0;
left: calc(50% - 21px / 2);
width: 21px; width: 21px;
height: 25px; height: 25px;
background-color: rgb(56, 57, 61); background-color: rgb(56, 57, 61);
@ -57,12 +66,6 @@
} }
} }
.notches {
position: absolute;
height: 100%;
width: 100%;
}
:host.disabled { :host.disabled {
filter: grayscale(80%); filter: grayscale(80%);
} }

View File

@ -25,7 +25,7 @@ export interface SkeuomorphSliderValueChangedEvent {
}) })
export class SkeuomorphSliderComponent implements OnInit { export class SkeuomorphSliderComponent implements OnInit {
constructor (private utils: UtilitiesService, private elRef: ElementRef) {} constructor (public utils: UtilitiesService, public elRef: ElementRef) {}
@Input() min: number = 0 @Input() min: number = 0
@Input() max: number = 1 @Input() max: number = 1
@ -40,8 +40,8 @@ export class SkeuomorphSliderComponent implements OnInit {
return typeof this.middle === 'number' ? this.middle : (this.min + this.max) / 2 return typeof this.middle === 'number' ? this.middle : (this.min + this.max) / 2
} }
private dragging = false public dragging = false
private doubleclickTimeout = null public doubleclickTimeout = null
@ViewChild('notches', { static: true }) notches @ViewChild('notches', { static: true }) notches
@Output() userChangedValue = new EventEmitter<SkeuomorphSliderValueChangedEvent>() @Output() userChangedValue = new EventEmitter<SkeuomorphSliderValueChangedEvent>()
@ -50,7 +50,7 @@ export class SkeuomorphSliderComponent implements OnInit {
@HostBinding('class.disabled') @Input() disabled = false @HostBinding('class.disabled') @Input() disabled = false
private _value = .5 public _value = .5
@Input() @Input()
set value (newValue) { set value (newValue) {
let value = this.clampValue(newValue) let value = this.clampValue(newValue)
@ -86,7 +86,7 @@ export class SkeuomorphSliderComponent implements OnInit {
} }
} }
private getValueFromMouseEvent (event) { public getValueFromMouseEvent (event) {
const coords = this.utils.getCoordinatesInsideElementFromEvent(event, this.elRef.nativeElement) const coords = this.utils.getCoordinatesInsideElementFromEvent(event, this.elRef.nativeElement)
const y = coords.y const y = coords.y
const height = this.elRef.nativeElement.offsetHeight const height = this.elRef.nativeElement.offsetHeight
@ -95,7 +95,7 @@ export class SkeuomorphSliderComponent implements OnInit {
return value return value
} }
private clampValue (value) { public clampValue (value) {
if (value < this.min) { if (value < this.min) {
return this.min return this.min
} else if (value > this.max) { } else if (value > this.max) {

View File

@ -1,13 +1,15 @@
<div #arrow <div class="container" [ngStyle]="style">
[hidden]="!showArrow" <div #arrow
class="arrow-container" [hidden]="!showArrow"
[ngStyle]="arrowStyle"> class="arrow-container"
<div [ngStyle]="arrowStyle">
class="arrow"></div> <div
</div> class="arrow"></div>
<eqm-container class="tooltip" #tooltip> </div>
<ng-content></ng-content> <eqm-container class="tooltip" #tooltip>
<eqm-label *ngIf="text"> <ng-content></ng-content>
{{text}} <eqm-label *ngIf="text">
</eqm-label> {{text}}
</eqm-container> </eqm-label>
</eqm-container>
</div>

View File

@ -1,34 +1,37 @@
:host {
.container {
display: block;
position: absolute; position: absolute;
// padding: 2px 3px; // padding: 2px 3px;
left: -100px; left: -100px;
top: -100px; top: -100px;
pointer-events: none; pointer-events: none;
z-index: 9999; z-index: 9999;
}
.tooltip {
text-align: center;
padding: 0px 4px;
white-space: pre;
}
.arrow-container { .tooltip {
position: absolute; text-align: center;
z-index: 9998; padding: 0px 4px;
width: 12px; white-space: pre;
height: 12px;
display: flex;
justify-content: center;
align-items: center;
clip-path: polygon(0 0, 100% 0, 100% 50%, 0 50%);
.arrow {
$ratio: 50%;
width: $ratio;
height: $ratio;
transform: rotate(45deg);
background-color: #222324;
box-shadow: 0 0 0 1px #000, 0 0 0 2px rgb(70, 74, 77);
border-radius: 10%;
} }
}
.arrow-container {
position: absolute;
z-index: 9998;
width: 12px;
height: 12px;
display: flex;
justify-content: center;
align-items: center;
clip-path: polygon(0 0, 100% 0, 100% 50%, 0 50%);
.arrow {
$ratio: 50%;
width: $ratio;
height: $ratio;
transform: rotate(45deg);
background-color: #222324;
box-shadow: 0 0 0 1px #000, 0 0 0 2px rgb(70, 74, 77);
border-radius: 10%;
}
}
}

View File

@ -3,8 +3,7 @@ import {
OnInit, OnInit,
Input, Input,
ElementRef, ElementRef,
ViewChild, ViewChild
HostBinding
} from '@angular/core' } from '@angular/core'
import { UtilitiesService } from '../../services/utilities.service' import { UtilitiesService } from '../../services/utilities.service'
import { SafeStyle, DomSanitizer } from '@angular/platform-browser' import { SafeStyle, DomSanitizer } from '@angular/platform-browser'
@ -20,7 +19,7 @@ export class TooltipComponent implements OnInit {
@Input() parent?: any @Input() parent?: any
@Input() positionSide: TooltipPositionSide = 'top' @Input() positionSide: TooltipPositionSide = 'top'
@Input() showArrow: Boolean = true @Input() showArrow: Boolean = true
private padding = 10 public padding = 10
@ViewChild('arrow', { @ViewChild('arrow', {
read: ElementRef, read: ElementRef,
@ -33,24 +32,23 @@ export class TooltipComponent implements OnInit {
}) tooltip }) tooltip
constructor ( constructor (
private elem: ElementRef, public elem: ElementRef,
private utils: UtilitiesService, public utils: UtilitiesService,
private sanitizer: DomSanitizer public sanitizer: DomSanitizer
) {} ) {}
async ngOnInit () { async ngOnInit () {
await this.utils.delay(0) await this.utils.delay(0)
} }
@HostBinding('style') get style () {
get style (): SafeStyle {
let x = -999 let x = -999
let y = -999 let y = -999
const body = document.body const body = document.body
const html = document.documentElement const html = document.documentElement
const viewHeight = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight) const viewHeight = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight)
const viewWidth = Math.max(body.scrollWidth, body.offsetWidth, html.clientWidth, html.scrollWidth, html.offsetWidth) const viewWidth = Math.max(body.scrollWidth, body.offsetWidth, html.clientWidth, html.scrollWidth, html.offsetWidth)
const tooltipEl = this.elem.nativeElement const tooltipEl = this.tooltip.nativeElement
const tooltipWidth = tooltipEl.offsetWidth + 3 const tooltipWidth = tooltipEl.offsetWidth + 3
const tooltipHeight = tooltipEl.offsetHeight + 2 const tooltipHeight = tooltipEl.offsetHeight + 2
const parentEl = this.parent.nativeElement const parentEl = this.parent.nativeElement
@ -86,7 +84,10 @@ export class TooltipComponent implements OnInit {
const minY = this.padding const minY = this.padding
if (y < minY) y = minY if (y < minY) y = minY
return this.sanitizer.bypassSecurityTrustStyle(`left: ${x}px; top: ${y}px`) return {
left: `${x}px`,
top: `${y}px`
}
} }
get arrowStyle () { get arrowStyle () {
@ -96,9 +97,9 @@ export class TooltipComponent implements OnInit {
let y = 0 let y = 0
let angle = 0 let angle = 0
const style: { [style: string]: string } = {} const style: { [style: string]: string } = {}
const tooltipEl = this.elem.nativeElement const tooltipEl = this.tooltip.nativeElement
const tooltipWidth = tooltipEl.offsetWidth + 3 const tooltipWidth = tooltipEl.offsetWidth
const tooltipHeight = tooltipEl.offsetHeight + 2 const tooltipHeight = tooltipEl.offsetHeight
const tooltipPosition = this.utils.getElementPosition(tooltipEl) const tooltipPosition = this.utils.getElementPosition(tooltipEl)
const parentEl = this.parent.nativeElement const parentEl = this.parent.nativeElement
@ -106,9 +107,9 @@ export class TooltipComponent implements OnInit {
const parentWidth = parentEl.offsetWidth const parentWidth = parentEl.offsetWidth
const parentHeight = parentEl.offsetHeight const parentHeight = parentEl.offsetHeight
x = parentPosition.x + parentWidth / 2 - tooltipPosition.x - arrowSize / 2 x = parentPosition.x + parentWidth / 2 - tooltipPosition.x - arrowSize / 2 + 3
if (this.positionSide === 'top') { if (this.positionSide === 'top') {
y = tooltipHeight - arrowSize / 2 - 3 y = tooltipHeight - arrowSize / 2 + 4
} }
if (this.positionSide === 'top') { if (this.positionSide === 'top') {
@ -116,7 +117,7 @@ export class TooltipComponent implements OnInit {
} }
if (this.positionSide === 'bottom') { if (this.positionSide === 'bottom') {
y = -arrowSize / 2 + 2 y = -arrowSize / 2 + 3
} }
style.top = `${y}px` style.top = `${y}px`

View File

@ -10,9 +10,9 @@ export class TooltipDirective implements OnDestroy {
@Input() eqmTooltipDelay = 100 @Input() eqmTooltipDelay = 100
@Input() eqmTooltipPositionSide: TooltipPositionSide = 'top' @Input() eqmTooltipPositionSide: TooltipPositionSide = 'top'
@Input() eqmTooltipShowArrow: boolean = true @Input() eqmTooltipShowArrow: boolean = true
private id: string public id: string
private left: boolean public left: boolean
constructor (private tooltipService: TooltipService, private element: ElementRef) { } constructor (public tooltipService: TooltipService, public element: ElementRef) { }
@HostListener('mouseenter') @HostListener('mouseenter')
onMouseEnter (): void { onMouseEnter (): void {

View File

@ -1,8 +1,8 @@
<eqm-loading *ngIf="!selectedPreset || !presets"></eqm-loading> <eqm-loading *ngIf="!selectedPreset || !presets"></eqm-loading>
<div *ngIf="selectedPreset && presets" fxLayoutAlign="start center" fxLayout="column" fxLayoutGap="10px" fxFill> <div *ngIf="selectedPreset && presets" fxLayoutAlign="start center" fxLayout="column" fxLayoutGap="10px" fxFill>
<div fxLayout="row" [style.width.%]="95" fxLayoutAlign="space-around center" fxLayoutGap="10px"> <div fxLayout="row" style="width: 95%" fxLayoutAlign="space-around center" fxLayoutGap="10px">
<eqm-value-screen [disabled]="!enabled">Global:</eqm-value-screen> <eqm-value-screen [disabled]="!enabled">Global:</eqm-value-screen>
<div [style.width.%]="90"> <div style="width: 90%">
<eqm-flat-slider [enabled]="enabled" [min]="-24" [max]="24" [(value)]="global" <eqm-flat-slider [enabled]="enabled" [min]="-24" [max]="24" [(value)]="global"
(userChangedValue)="setGain('global', $event)" [stickToMiddle]="stickSlidersToMiddle" (userChangedValue)="setGain('global', $event)" [stickToMiddle]="stickSlidersToMiddle"
(stickedToMiddle)="performHapticFeedback()" orientation="horizontal"> (stickedToMiddle)="performHapticFeedback()" orientation="horizontal">

View File

@ -20,7 +20,7 @@ import { ApplicationService } from '../../../../services/app.service'
export class AdvancedEqualizerComponent extends EqualizerComponent implements OnInit { export class AdvancedEqualizerComponent extends EqualizerComponent implements OnInit {
@Input() enabled = true @Input() enabled = true
private ShowDefaultPresetsCheckbox: CheckboxOption = { public ShowDefaultPresetsCheckbox: CheckboxOption = {
key: 'show-default-presets', key: 'show-default-presets',
type: 'checkbox', type: 'checkbox',
label: 'Show Default Presets', label: 'Show Default Presets',
@ -42,7 +42,7 @@ export class AdvancedEqualizerComponent extends EqualizerComponent implements On
], [ ], [
this.ShowDefaultPresetsCheckbox this.ShowDefaultPresetsCheckbox
]] ]]
private _presets: AdvancedEqualizerPreset[] public _presets: AdvancedEqualizerPreset[]
@Output() presetsChange = new EventEmitter<AdvancedEqualizerPreset[]>() @Output() presetsChange = new EventEmitter<AdvancedEqualizerPreset[]>()
set presets (newPresets: AdvancedEqualizerPreset[]) { set presets (newPresets: AdvancedEqualizerPreset[]) {
this._presets = this._presets =
@ -55,7 +55,7 @@ export class AdvancedEqualizerComponent extends EqualizerComponent implements On
} }
get presets () { return this._presets } get presets () { return this._presets }
private _selectedPreset: AdvancedEqualizerPreset public _selectedPreset: AdvancedEqualizerPreset
@Output() selectedPresetChange = new EventEmitter<AdvancedEqualizerPreset>() @Output() selectedPresetChange = new EventEmitter<AdvancedEqualizerPreset>()
set selectedPreset (newSelectedPreset: AdvancedEqualizerPreset) { set selectedPreset (newSelectedPreset: AdvancedEqualizerPreset) {
this._selectedPreset = newSelectedPreset this._selectedPreset = newSelectedPreset
@ -100,10 +100,10 @@ export class AdvancedEqualizerComponent extends EqualizerComponent implements On
} }
constructor ( constructor (
private service: AdvancedEqualizerService, public service: AdvancedEqualizerService,
private transition: TransitionService, public transition: TransitionService,
private change: ChangeDetectorRef, public change: ChangeDetectorRef,
private app: ApplicationService public app: ApplicationService
) { ) {
super() super()
this.getImportLegacyAvailable() this.getImportLegacyAvailable()
@ -121,7 +121,7 @@ export class AdvancedEqualizerComponent extends EqualizerComponent implements On
]) ])
} }
private async getImportLegacyAvailable () { public async getImportLegacyAvailable () {
if (await this.service.getImportLegacyAvailable()) { if (await this.service.getImportLegacyAvailable()) {
this.settings[1].push( this.settings[1].push(
{ {
@ -138,7 +138,7 @@ export class AdvancedEqualizerComponent extends EqualizerComponent implements On
) )
} }
} }
private async syncPresets () { public async syncPresets () {
const [ presets, selectedPreset ] = await Promise.all([ const [ presets, selectedPreset ] = await Promise.all([
this.service.getPresets(), this.service.getPresets(),
this.service.getSelectedPreset() this.service.getSelectedPreset()
@ -148,13 +148,13 @@ export class AdvancedEqualizerComponent extends EqualizerComponent implements On
this.setSelectedPresetsGains() this.setSelectedPresetsGains()
} }
private async syncSettings () { public async syncSettings () {
return Promise.all([ return Promise.all([
this.syncShowDefaultPresets() this.syncShowDefaultPresets()
]) ])
} }
private async syncShowDefaultPresets () { public async syncShowDefaultPresets () {
this.ShowDefaultPresetsCheckbox.value = await this.service.getShowDefaultPresets() this.ShowDefaultPresetsCheckbox.value = await this.service.getShowDefaultPresets()
} }

View File

@ -2,7 +2,7 @@
<div *ngIf="selectedPreset && presets" fxLayout="column" fxLayoutAlign="start center" fxLayoutGap="10px"> <div *ngIf="selectedPreset && presets" fxLayout="column" fxLayoutAlign="start center" fxLayoutGap="10px">
<div fxLayout="row"> <div fxLayout="row">
<div fxLayout="column"> <div fxLayout="column">
<div fxLayout="row" fxLayoutAlign="center center" fxFill fxLayoutGap="10px" (click)="togglePeakLimiter()"> <div fxLayout="row" fxLayoutAlign="center center" style="width: 100%;" fxLayoutGap="10px" (click)="togglePeakLimiter()">
<eqm-checkbox [interactive]="false" [checked]="peakLimiter"></eqm-checkbox> <eqm-checkbox [interactive]="false" [checked]="peakLimiter"></eqm-checkbox>
<eqm-label>Peak Limiter</eqm-label> <eqm-label>Peak Limiter</eqm-label>
<eqm-question <eqm-question
@ -17,7 +17,7 @@ Then increase the overall volume to compensate'
</div> </div>
<!-- Knobs --> <!-- Knobs -->
<div *ngIf="!replaceKnobsWithSliders" class="basic-level-knobs" fxFill fxLayout="row" <div *ngIf="!replaceKnobsWithSliders" class="basic-level-knobs" style="width: 100%;" fxLayout="row"
fxLayoutAlign="space-around center"> fxLayoutAlign="space-around center">
<div fxLayout="column" fxLayoutAlign="center center" fxLayoutGap="5px"> <div fxLayout="column" fxLayoutAlign="center center" fxLayoutGap="5px">
<eqm-label>BASS</eqm-label> <eqm-label>BASS</eqm-label>

View File

@ -24,7 +24,7 @@ export class BasicEqualizerComponent extends EqualizerComponent implements OnIni
replaceKnobsWithSliders = false replaceKnobsWithSliders = false
private _presets: BasicEqualizerPreset[] public _presets: BasicEqualizerPreset[]
@Output() presetsChange = new EventEmitter<BasicEqualizerPreset[]>() @Output() presetsChange = new EventEmitter<BasicEqualizerPreset[]>()
set presets (newPresets: BasicEqualizerPreset[]) { set presets (newPresets: BasicEqualizerPreset[]) {
this._presets = this._presets =
@ -37,7 +37,7 @@ export class BasicEqualizerComponent extends EqualizerComponent implements OnIni
} }
get presets () { return this._presets } get presets () { return this._presets }
private _selectedPreset: BasicEqualizerPreset public _selectedPreset: BasicEqualizerPreset
@Output() selectedPresetChange = new EventEmitter<BasicEqualizerPreset>() @Output() selectedPresetChange = new EventEmitter<BasicEqualizerPreset>()
set selectedPreset (newSelectedPreset: BasicEqualizerPreset) { set selectedPreset (newSelectedPreset: BasicEqualizerPreset) {
this._selectedPreset = newSelectedPreset this._selectedPreset = newSelectedPreset
@ -48,11 +48,11 @@ export class BasicEqualizerComponent extends EqualizerComponent implements OnIni
settings = [] settings = []
constructor ( constructor (
private service: BasicEqualizerService, public service: BasicEqualizerService,
private app: ApplicationService, public app: ApplicationService,
private ui: UIService, public ui: UIService,
private change: ChangeDetectorRef, public change: ChangeDetectorRef,
private transition: TransitionService public transition: TransitionService
) { ) {
super() super()
} }

View File

@ -1,4 +1,4 @@
<div fxLayout="row" [style.padding.px]="5" fxLayoutAlign="space-between start" fxFill> <div fxLayout="row" [style.padding.px]="5" [style.width.%]="100" fxLayoutAlign="space-between start" >
<div fxFlex="20" fxLayoutAlign="start center"> <div fxFlex="20" fxLayoutAlign="start center">
<eqm-toggle class="on-off" [(state)]="enabled" (stateChange)="setEnabled()"></eqm-toggle> <eqm-toggle class="on-off" [(state)]="enabled" (stateChange)="setEnabled()"></eqm-toggle>
@ -29,7 +29,7 @@
<!-- <eqm-icon (click)="toggleVisibility()" [name]="hide ? 'show' : 'hide'"></eqm-icon> --> <!-- <eqm-icon (click)="toggleVisibility()" [name]="hide ? 'show' : 'hide'"></eqm-icon> -->
</div> </div>
</div> </div>
<div fxFill fxLayout="row"> <div [style.width.%]="100" fxLayout="row">
<eqm-equalizer-presets <eqm-equalizer-presets
[disabled]="!enabled" [disabled]="!enabled"
class="presets" class="presets"

View File

@ -28,7 +28,7 @@ export class EqualizersComponent implements OnInit {
loaded = false loaded = false
enabled = true enabled = true
hide = false hide = false
activeEqualizer: EqualizerComponent activeEqualizer: EqualizerComponent = this.getEqualizerFromType('Basic')
presets: EqualizerPreset[] = [] presets: EqualizerPreset[] = []
selectedPreset: EqualizerPreset selectedPreset: EqualizerPreset
@ -48,11 +48,11 @@ export class EqualizersComponent implements OnInit {
this.equalizersService.setType(newType) this.equalizersService.setType(newType)
} }
private settingsDialog: MatDialogRef<OptionsDialogComponent> public settingsDialog: MatDialogRef<OptionsDialogComponent>
constructor ( constructor (
private equalizersService: EqualizersService, public equalizersService: EqualizersService,
private dialog: MatDialog, public dialog: MatDialog,
protected ui: UIService protected ui: UIService
) { } ) { }
@ -108,7 +108,7 @@ export class EqualizersComponent implements OnInit {
this.ui.dimensionsChanged.next({ heightDiff }) this.ui.dimensionsChanged.next({ heightDiff })
} }
private getEqualizerFromType (type: EqualizerType): EqualizerComponent { public getEqualizerFromType (type: EqualizerType): EqualizerComponent {
switch (type) { switch (type) {
case 'Basic': return this.basicEqualizer case 'Basic': return this.basicEqualizer
case 'Advanced': return this.advancedEqualizer case 'Advanced': return this.advancedEqualizer

View File

@ -23,7 +23,7 @@ export class EqualizerPresetsComponent implements OnInit {
@Output() presetDeleted = new EventEmitter() @Output() presetDeleted = new EventEmitter()
constructor ( constructor (
private dialog: MatDialog public dialog: MatDialog
) { } ) { }
ngOnInit () { ngOnInit () {

View File

@ -22,7 +22,7 @@ export class ReverbComponent implements OnInit {
@Output() visibilityToggled = new EventEmitter() @Output() visibilityToggled = new EventEmitter()
constructor (private reverbService: ReverbService) {} constructor (public reverbService: ReverbService) {}
ngOnInit () { ngOnInit () {
this.getPresets() this.getPresets()

View File

@ -21,10 +21,10 @@ export class HeaderComponent implements OnInit {
@Output() helpToggled = new EventEmitter() @Output() helpToggled = new EventEmitter()
// mode: UIMode = 'popover' // mode: UIMode = 'popover'
constructor ( constructor (
private app: ApplicationService, public app: ApplicationService,
private ui: UIService, public ui: UIService,
private dialog: MatDialog, public dialog: MatDialog,
private settings: SettingsService public settings: SettingsService
) { } ) { }
async ngOnInit () { async ngOnInit () {

View File

@ -30,7 +30,7 @@ export class HelpComponent implements OnInit {
constructor ( constructor (
public app: ApplicationService, public app: ApplicationService,
public CONST: ConstantsService, public CONST: ConstantsService,
private ui: UIService public ui: UIService
) {} ) {}
uiVersion = `${version} (${this.ui.isLocal ? 'Local' : 'Remote'})` uiVersion = `${version} (${this.ui.isLocal ? 'Local' : 'Remote'})`

View File

@ -9,7 +9,7 @@ import { OutputsService, Output } from './outputs.service'
export class OutputsComponent implements OnInit { export class OutputsComponent implements OnInit {
outputs: Output[] outputs: Output[]
selected: Output selected: Output
constructor (private service: OutputsService) { } constructor (public service: OutputsService) { }
async ngOnInit () { async ngOnInit () {
await this.sync() await this.sync()

View File

@ -93,7 +93,7 @@ export class SettingsComponent implements OnInit {
public settingsService: SettingsService, public settingsService: SettingsService,
public app: ApplicationService, public app: ApplicationService,
public dialog: MatDialog, public dialog: MatDialog,
private ui: UIService public ui: UIService
) { ) {
this.getDriverReinstallAvailable() this.getDriverReinstallAvailable()
} }

View File

@ -27,15 +27,15 @@ export class FileComponent implements OnInit, OnDestroy {
name: null, name: null,
duration: 0 duration: 0
} }
private syncedOnce = false public syncedOnce = false
private progressProjectionInterval = null public progressProjectionInterval = null
private progressSetDebouncer = null public progressSetDebouncer = null
selected = false selected = false
meta: FileMeta = null meta: FileMeta = null
playing = false playing = false
progress = 0 progress = 0
constructor (private fileService: FileService, public utils: UtilitiesService, private app: ApplicationService) { constructor (public fileService: FileService, public utils: UtilitiesService, public app: ApplicationService) {
this.setDefaultMeta() this.setDefaultMeta()
} }
@ -50,11 +50,11 @@ export class FileComponent implements OnInit, OnDestroy {
} }
} }
private setDefaultMeta () { public setDefaultMeta () {
this.meta = this.utils.deepCloneJSON(this.defaultMeta) this.meta = this.utils.deepCloneJSON(this.defaultMeta)
} }
private setProgressProjection () { public setProgressProjection () {
const refreshFPS = 30 const refreshFPS = 30
if (this.progressProjectionInterval) { if (this.progressProjectionInterval) {

View File

@ -14,7 +14,7 @@ export interface InputDevice {
}) })
export class InputComponent implements OnInit { export class InputComponent implements OnInit {
constructor (private inputService: InputService) { } constructor (public inputService: InputService) { }
devices: InputDevice[] = [] devices: InputDevice[] = []
selectedDevice: InputDevice = null selectedDevice: InputDevice = null

View File

@ -9,7 +9,7 @@ import { SourceService, SourceType } from './source.service'
export class SourceComponent implements OnInit { export class SourceComponent implements OnInit {
source: SourceType = 'File' source: SourceType = 'File'
constructor (private sourceService: SourceService) { } constructor (public sourceService: SourceService) { }
ngOnInit () { ngOnInit () {
this.setupEvents() this.setupEvents()

View File

@ -19,8 +19,8 @@ export class BalanceComponent implements OnInit {
constructor ( constructor (
public balanceService: BalanceService, public balanceService: BalanceService,
private app: ApplicationService, public app: ApplicationService,
private ui: UIService public ui: UIService
) { } ) { }
ngOnInit () { ngOnInit () {

View File

@ -21,9 +21,9 @@ export class BoosterComponent implements OnInit {
constructor ( constructor (
public boosterService: BoosterService, public boosterService: BoosterService,
private app: ApplicationService, public app: ApplicationService,
private changeRef: ChangeDetectorRef, public changeRef: ChangeDetectorRef,
private ui: UIService public ui: UIService
) {} ) {}
ngOnInit () { ngOnInit () {
@ -38,8 +38,8 @@ export class BoosterComponent implements OnInit {
]) ])
} }
private ignoreUpdates = false public ignoreUpdates = false
private ignoreUpdatesDebouncer: NodeJS.Timer public ignoreUpdatesDebouncer: NodeJS.Timer
protected setupEvents () { protected setupEvents () {
this.boosterService.onGainChanged(gain => { this.boosterService.onGainChanged(gain => {
if (!this.ignoreUpdates) { if (!this.ignoreUpdates) {

View File

@ -1,6 +1,6 @@
<div *ngIf="!replaceKnobsWithSliders" fxLayout="row" fxFill fxLayoutAlign="space-around stretch"> <div *ngIf="!replaceKnobsWithSliders" fxLayout="row" fxFill fxLayoutAlign="space-around stretch">
<eqm-booster fxFlex="49%" [hide]="hide"></eqm-booster> <eqm-booster fxFlex="49%" [hide]="hide"></eqm-booster>
<eqm-divider [vertical]="true"></eqm-divider> <eqm-divider orientation="vertical"></eqm-divider>
<eqm-balance fxFlex="49%" [hide]="hide"></eqm-balance> <eqm-balance fxFlex="49%" [hide]="hide"></eqm-balance>
</div> </div>

View File

@ -11,7 +11,7 @@ export class VolumeBoosterBalanceComponent implements OnInit {
replaceKnobsWithSliders = false replaceKnobsWithSliders = false
@Output() visibilityToggled = new EventEmitter() @Output() visibilityToggled = new EventEmitter()
constructor ( constructor (
private ui: UIService public ui: UIService
) { } ) { }
async ngOnInit () { async ngOnInit () {

View File

@ -8,11 +8,11 @@ import { version } from '../../../package.json'
}) })
export class AnalyticsService { export class AnalyticsService {
constructor ( constructor (
private utils: UtilitiesService, public utils: UtilitiesService,
private app: ApplicationService public app: ApplicationService
) {} ) {}
private async load () { public async load () {
await this.utils.waitForProperty(window, 'ga') await this.utils.waitForProperty(window, 'ga')
await this.utils.delay(1000) await this.utils.delay(1000)
await this.utils.waitForProperty(ga, 'getAll') await this.utils.waitForProperty(ga, 'getAll')

View File

@ -30,10 +30,10 @@ interface JSBridge {
providedIn: 'root' providedIn: 'root'
}) })
export class BridgeService { export class BridgeService {
private static bridgeLoadTimeout = 10000 public static bridgeLoadTimeout = 10000
private static bridgeLoadPromise: Promise<JSBridge> = null public static bridgeLoadPromise: Promise<JSBridge> = null
private get bridge () { public get bridge () {
if (BridgeService.bridgeLoadPromise) { if (BridgeService.bridgeLoadPromise) {
return BridgeService.bridgeLoadPromise return BridgeService.bridgeLoadPromise
} }

View File

@ -8,7 +8,7 @@ import { environment } from '../../environments/environment'
}) })
export class CookiesService { export class CookiesService {
constructor ( constructor (
private CONST: ConstantsService public CONST: ConstantsService
) {} ) {}
set (key: string, value: any) { set (key: string, value: any) {
if (typeof value !== 'string') { if (typeof value !== 'string') {

View File

@ -5,7 +5,7 @@ export class Logger {
this.console('log', ...something) this.console('log', ...something)
} }
private static console (func: 'log' , ...something: any[]) { public static console (func: 'log' , ...something: any[]) {
if (!environment.production) { if (!environment.production) {
console[func](...something) console[func](...something)
} }

View File

@ -2,6 +2,7 @@
<html lang="en"> <html lang="en">
<head> <head>
<!-- Google Tag Manager --> <!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': <script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],

View File

@ -52,7 +52,7 @@
* Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
* Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
**/ **/
// import 'web-animations-js'; // Run `npm install --save web-animations-js`. import 'web-animations-js' // Run `npm install --save web-animations-js`.
/** /**
* By default, zone.js will patch all possible macroTask and DomEvents * By default, zone.js will patch all possible macroTask and DomEvents