mirror of
https://github.com/Myxelium/Bridge-Multi.git
synced 2026-04-09 05:09:39 +00:00
Difficulty info and source folder links
This commit is contained in:
@@ -16,7 +16,22 @@
|
||||
<div><b>{{charterPlural}}</b> {{selectedVersion.charters}}</div>
|
||||
<div *ngIf="selectedVersion.tags"><b>Tags:</b> {{selectedVersion.tags}}</div>
|
||||
<div><b>Audio Length:</b> {{songLength}}</div>
|
||||
<!-- TODO: add difficulty icons -->
|
||||
<div class="ui divider"></div>
|
||||
<div class="ui horizontal list">
|
||||
<div *ngFor="let difficulty of difficultiesList" class="item">
|
||||
<img class="ui avatar image" src="/assets/images/instruments/{{difficulty.instrument}}">
|
||||
<div class="content">
|
||||
<div class="header">Diff: {{difficulty.diffNumber}}</div>
|
||||
{{difficulty.chartedDifficulties}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="sourceLinks">
|
||||
<a id="sourceLink" (click)="onSourceLinkClicked()">{{selectedVersion.driveData.source.sourceName}}</a>
|
||||
<button *ngIf="shownFolderButton()" id="folderButton" class="mini ui icon button" (click)="onFolderButtonClicked()">
|
||||
<i class="folder open outline icon"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
#versionDropdown {
|
||||
#versionDropdown, #folderButton {
|
||||
max-width: min-content;
|
||||
}
|
||||
|
||||
@@ -25,12 +25,29 @@
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
#sourceLinks {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#sourceLink {
|
||||
align-self: center;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
#chartDropdownIcon, #versionDropdown {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.ui.horizontal.list>.item {
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.ui.divider {
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
#downloadButton {
|
||||
width: min-content;
|
||||
}
|
||||
@@ -1,13 +1,19 @@
|
||||
import { Component, OnInit } from '@angular/core'
|
||||
import { SongResult } from '../../../../electron/shared/interfaces/search.interface'
|
||||
import { ElectronService } from '../../../core/services/electron.service'
|
||||
import { VersionResult } from '../../../../electron/shared/interfaces/songDetails.interface'
|
||||
import { VersionResult, getInstrumentIcon, Instrument, ChartedDifficulty } from '../../../../electron/shared/interfaces/songDetails.interface'
|
||||
import { AlbumArtService } from '../../../core/services/album-art.service'
|
||||
import { DownloadService } from '../../../core/services/download.service'
|
||||
import { groupBy } from 'src/electron/shared/UtilFunctions'
|
||||
import { SearchService } from 'src/app/core/services/search.service'
|
||||
import { DomSanitizer, SafeUrl } from '@angular/platform-browser'
|
||||
|
||||
interface Difficulty {
|
||||
instrument: string
|
||||
diffNumber: string
|
||||
chartedDifficulties: string
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-chart-sidebar',
|
||||
templateUrl: './chart-sidebar.component.html',
|
||||
@@ -110,6 +116,7 @@ export class ChartSidebarComponent implements OnInit {
|
||||
if (this.selectedVersion != undefined) {
|
||||
this.updateCharterPlural()
|
||||
this.updateSongLength()
|
||||
this.updateDifficultiesList()
|
||||
this.updateDownloadButtonText()
|
||||
}
|
||||
}
|
||||
@@ -118,7 +125,7 @@ export class ChartSidebarComponent implements OnInit {
|
||||
/**
|
||||
* Chooses to display 'Charter:' or 'Charters:'.
|
||||
*/
|
||||
updateCharterPlural() {
|
||||
private updateCharterPlural() {
|
||||
this.charterPlural = this.selectedVersion.charterIDs.split('&').length == 1 ? 'Charter:' : 'Charters:'
|
||||
}
|
||||
|
||||
@@ -126,7 +133,7 @@ export class ChartSidebarComponent implements OnInit {
|
||||
/**
|
||||
* Converts `this.selectedVersion.chartMetadata.length` into a readable duration.
|
||||
*/
|
||||
updateSongLength() {
|
||||
private updateSongLength() {
|
||||
let seconds = this.selectedVersion.songLength
|
||||
if (seconds < 60) { this.songLength = `${seconds} second${seconds == 1 ? '' : 's'}`; return }
|
||||
let minutes = Math.floor(seconds / 60)
|
||||
@@ -139,11 +146,50 @@ export class ChartSidebarComponent implements OnInit {
|
||||
this.songLength = `${hours == 0 ? '' : hours + ':'}${minutes == 0 ? '' : minutes + ':'}${seconds < 10 ? '0' + seconds : seconds}`
|
||||
}
|
||||
|
||||
difficultiesList: Difficulty[]
|
||||
/**
|
||||
* Updates `dfficultiesList` with the difficulty information for the selected version.
|
||||
*/
|
||||
private updateDifficultiesList() {
|
||||
const instruments = Object.keys(this.selectedVersion.chartData.noteCounts) as Instrument[]
|
||||
this.difficultiesList = []
|
||||
for (const instrument of instruments) {
|
||||
this.difficultiesList.push({
|
||||
instrument: getInstrumentIcon(instrument),
|
||||
diffNumber: this.getDiffNumber(instrument),
|
||||
chartedDifficulties: this.getChartedDifficultiesText(instrument)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns a string describing the difficulty number in the selected version.
|
||||
*/
|
||||
private getDiffNumber(instrument: Instrument) {
|
||||
const diffNumber: number = this.selectedVersion[`diff_${instrument}`]
|
||||
return diffNumber == -1 || diffNumber == undefined ? 'Unknown' : String(diffNumber)
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns a string describing the list of charted difficulties in the selected version.
|
||||
*/
|
||||
private getChartedDifficultiesText(instrument: Instrument) {
|
||||
const difficulties = Object.keys(this.selectedVersion.chartData.noteCounts[instrument]) as ChartedDifficulty[]
|
||||
if (difficulties.length == 4) { return 'Full Difficulty' }
|
||||
const difficultyNames = []
|
||||
if (difficulties.includes('x')) { difficultyNames.push('Expert') }
|
||||
if (difficulties.includes('h')) { difficultyNames.push('Hard') }
|
||||
if (difficulties.includes('m')) { difficultyNames.push('Medium') }
|
||||
if (difficulties.includes('e')) { difficultyNames.push('Easy') }
|
||||
|
||||
return difficultyNames.join(', ')
|
||||
}
|
||||
|
||||
downloadButtonText: string
|
||||
/**
|
||||
* Chooses the text to display on the download button.
|
||||
*/
|
||||
updateDownloadButtonText() {
|
||||
private updateDownloadButtonText() {
|
||||
this.downloadButtonText = 'Download'
|
||||
if (this.selectedVersion.driveData.inChartPack) {
|
||||
this.downloadButtonText += ' Chart Pack'
|
||||
@@ -198,6 +244,29 @@ export class ChartSidebarComponent implements OnInit {
|
||||
return `${month}/${day}/${year}`
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the proxy link or source folder in the default browser.
|
||||
*/
|
||||
onSourceLinkClicked() {
|
||||
const source = this.selectedVersion.driveData.source
|
||||
this.electronService.sendIPC('open-url', source.proxyLink ?? `https://drive.google.com/drive/folders/${source.sourceDriveID}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns `true` if the source folder button should be shown.
|
||||
*/
|
||||
shownFolderButton() {
|
||||
const driveData = this.selectedVersion.driveData
|
||||
return driveData.source.proxyLink || driveData.source.sourceDriveID != driveData.folderID
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the chart folder in the default browser.
|
||||
*/
|
||||
onFolderButtonClicked() {
|
||||
this.electronService.sendIPC('open-url', `https://drive.google.com/drive/folders/${this.selectedVersion.driveData.folderID}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the selected version to the download queue.
|
||||
*/
|
||||
|
||||
BIN
src/assets/images/instruments/bass.png
Normal file
BIN
src/assets/images/instruments/bass.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
BIN
src/assets/images/instruments/bassghl.png
Normal file
BIN
src/assets/images/instruments/bassghl.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
1
src/assets/images/instruments/drums.svg
Normal file
1
src/assets/images/instruments/drums.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg fill="#000" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" version="1.1" style="shape-rendering:geometricPrecision;text-rendering:geometricPrecision;image-rendering:optimizeQuality;" viewBox="0 0 1000 1000" x="0px" y="0px" fill-rule="evenodd" clip-rule="evenodd"><g transform="translate(75 100)"><path full="#fff" class="fil0" d="M164 131c-48,-13 -82,-88 -38,-119 44,-32 104,24 101,74 93,125 149,200 196,264 48,-64 103,-139 197,-264 -4,-50 57,-106 101,-74 44,31 10,106 -38,119 -58,83 -130,187 -205,294 58,78 123,166 254,342 37,51 -46,107 -81,58 -65,-89 -146,-204 -228,-322 -82,118 -163,233 -227,322 -36,49 -118,-7 -81,-58 131,-176 196,-264 253,-342 -74,-107 -146,-211 -204,-294zm241 346l-19 -27 -248 334c-13,19 21,43 34,25l233 -332zm36 -102l18 24 201 -286c2,-5 6,-8 12,-9 28,-5 54,-53 32,-69 -23,-16 -60,24 -55,53 1,4 -1,9 -4,12l-204 275zm233 434c14,18 48,-6 34,-25l-506 -684c-3,-3 -5,-8 -4,-12 5,-29 -32,-69 -55,-53 -22,16 3,64 32,69 5,1 10,4 12,9l487 696z"></path></g></svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
BIN
src/assets/images/instruments/guitar.png
Normal file
BIN
src/assets/images/instruments/guitar.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
BIN
src/assets/images/instruments/guitarghl.png
Normal file
BIN
src/assets/images/instruments/guitarghl.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
BIN
src/assets/images/instruments/keys.png
Normal file
BIN
src/assets/images/instruments/keys.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.8 KiB |
18
src/electron/ipc/OpenURLHandler.ipc.ts
Normal file
18
src/electron/ipc/OpenURLHandler.ipc.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { IPCEmitHandler } from '../shared/IPCHandler'
|
||||
import { shell } from 'electron'
|
||||
|
||||
/**
|
||||
* Handles the 'open-url' event.
|
||||
*/
|
||||
class OpenURLHandler implements IPCEmitHandler<'open-url'> {
|
||||
event: 'open-url' = 'open-url'
|
||||
|
||||
/**
|
||||
* Opens `url` in the default browser.
|
||||
*/
|
||||
handler(url: string) {
|
||||
shell.openExternal(url)
|
||||
}
|
||||
}
|
||||
|
||||
export const openURLHandler = new OpenURLHandler()
|
||||
@@ -115,7 +115,7 @@ class APIFileDownloader {
|
||||
if (this.wasCanceled) { return }
|
||||
this.startDownloadStream()
|
||||
} else {
|
||||
console.log(err)
|
||||
console.log(JSON.stringify(err))
|
||||
this.failDownload(downloadErrors.responseError(err ? (err.code ?? 'unknown') : 'unknown'))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import { getSettingsHandler, setSettingsHandler } from '../ipc/SettingsHandler.i
|
||||
import { googleLoginHandler, getAuthStatusHandler, googleLogoutHandler } from '../ipc/google/GoogleLoginHandler.ipc'
|
||||
import { UpdateProgress, getCurrentVersionHandler, downloadUpdateHandler, quitAndInstallHandler, getUpdateAvailableHandler } from '../ipc/UpdateHandler.ipc'
|
||||
import { UpdateInfo } from 'electron-updater'
|
||||
import { openURLHandler } from '../ipc/OpenURLHandler.ipc'
|
||||
|
||||
/**
|
||||
* To add a new IPC listener:
|
||||
@@ -95,7 +96,8 @@ export function getIPCEmitHandlers(): IPCEmitHandler<keyof IPCEmitEvents>[] {
|
||||
downloadHandler,
|
||||
setSettingsHandler,
|
||||
downloadUpdateHandler,
|
||||
quitAndInstallHandler
|
||||
quitAndInstallHandler,
|
||||
openURLHandler
|
||||
]
|
||||
}
|
||||
|
||||
@@ -114,6 +116,7 @@ export type IPCEmitEvents = {
|
||||
'update-downloaded': undefined
|
||||
'download-update': undefined
|
||||
'quit-and-install': undefined
|
||||
'open-url': string
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -83,12 +83,28 @@ export interface ChartData {
|
||||
is120: boolean
|
||||
hasBrokenNotes: boolean
|
||||
noteCounts: {
|
||||
[instrument: string]: {
|
||||
[difficulty: string]: number
|
||||
[instrument in Instrument]: {
|
||||
[difficulty in ChartedDifficulty]: number
|
||||
}
|
||||
}
|
||||
/** number of seconds */
|
||||
length: number
|
||||
/** number of seconds */
|
||||
effectiveLength: number
|
||||
}
|
||||
|
||||
export type Instrument = 'guitar' | 'bass' | 'rhythm' | 'keys' | 'drums' | 'guitarghl' | 'bassghl' | 'vocals'
|
||||
export type ChartedDifficulty = 'x' | 'h' | 'm' | 'e'
|
||||
|
||||
export function getInstrumentIcon(instrument: Instrument) {
|
||||
switch(instrument) {
|
||||
case 'guitar': return 'guitar.png'
|
||||
case 'bass': return 'bass.png'
|
||||
case 'rhythm': return 'guitar.png' // TODO: get unique icon
|
||||
case 'keys': return 'keys.png'
|
||||
case 'drums': return 'drums.svg'
|
||||
case 'guitarghl': return 'guitarghl.png'
|
||||
case 'bassghl': return 'bassghl.png'
|
||||
case 'vocals': return 'guitar.png' // TODO: get unique icon
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user