├── .browserslistrc ├── .editorconfig ├── .github └── workflows │ └── main.yml ├── .gitignore ├── README.md ├── angular.json ├── e2e ├── protractor.conf.js ├── src │ ├── app.e2e-spec.ts │ └── app.po.ts └── tsconfig.json ├── karma.conf.js ├── ngsw-config.json ├── package-lock.json ├── package.json ├── src ├── app │ ├── api.service.ts │ ├── app-routing.module.ts │ ├── app.component.css │ ├── app.component.html │ ├── app.component.spec.ts │ ├── app.component.ts │ ├── app.module.ts │ ├── auth │ │ ├── auth-guard.service.spec.ts │ │ ├── auth-guard.service.ts │ │ ├── authentication.service.spec.ts │ │ ├── authentication.service.ts │ │ ├── error-interceptor.service.spec.ts │ │ ├── error-interceptor.service.ts │ │ ├── loading-interceptor.service.spec.ts │ │ └── loading-interceptor.service.ts │ ├── changelog │ │ ├── changelog.component.css │ │ ├── changelog.component.html │ │ ├── changelog.component.spec.ts │ │ └── changelog.component.ts │ ├── dashboard │ │ ├── dashboard.component.css │ │ ├── dashboard.component.html │ │ ├── dashboard.component.spec.ts │ │ ├── dashboard.component.ts │ │ └── dashboard.module.ts │ ├── database │ │ ├── database.module.ts │ │ ├── preload.service.spec.ts │ │ └── preload.service.ts │ ├── importer │ │ ├── importer.module.ts │ │ └── importer │ │ │ ├── importer.component.css │ │ │ ├── importer.component.html │ │ │ ├── importer.component.spec.ts │ │ │ └── importer.component.ts │ ├── login │ │ ├── login.component.css │ │ ├── login.component.html │ │ ├── login.component.spec.ts │ │ ├── login.component.ts │ │ └── login.module.ts │ ├── message.service.ts │ ├── message │ │ ├── message.component.css │ │ ├── message.component.html │ │ ├── message.component.spec.ts │ │ ├── message.component.ts │ │ └── message.module.ts │ ├── model │ │ ├── Page.ts │ │ └── PropertyEntry.ts │ ├── sega │ │ ├── chunithm │ │ │ └── amazon │ │ │ │ ├── amazon-character │ │ │ │ ├── amazon-character.component.css │ │ │ │ ├── amazon-character.component.html │ │ │ │ ├── amazon-character.component.spec.ts │ │ │ │ └── amazon-character.component.ts │ │ │ │ ├── amazon-profile │ │ │ │ ├── amazon-profile.component.css │ │ │ │ ├── amazon-profile.component.html │ │ │ │ ├── amazon-profile.component.spec.ts │ │ │ │ └── amazon-profile.component.ts │ │ │ │ ├── amazon-rating │ │ │ │ ├── amazon-rating.component.css │ │ │ │ ├── amazon-rating.component.html │ │ │ │ ├── amazon-rating.component.spec.ts │ │ │ │ └── amazon-rating.component.ts │ │ │ │ ├── amazon-recent │ │ │ │ ├── amazon-recent.component.css │ │ │ │ ├── amazon-recent.component.html │ │ │ │ ├── amazon-recent.component.spec.ts │ │ │ │ └── amazon-recent.component.ts │ │ │ │ ├── amazon-setting │ │ │ │ ├── amazon-name-setting │ │ │ │ │ ├── amazon-name-setting.dialog.ts │ │ │ │ │ └── amazon-name-setting.html │ │ │ │ ├── amazon-setting.component.css │ │ │ │ ├── amazon-setting.component.html │ │ │ │ ├── amazon-setting.component.spec.ts │ │ │ │ └── amazon-setting.component.ts │ │ │ │ ├── amazon-song-detail │ │ │ │ ├── amazon-song-detail.component.css │ │ │ │ ├── amazon-song-detail.component.html │ │ │ │ ├── amazon-song-detail.component.spec.ts │ │ │ │ └── amazon-song-detail.component.ts │ │ │ │ ├── amazon-song-playlog │ │ │ │ ├── amazon-song-playlog.component.css │ │ │ │ ├── amazon-song-playlog.component.html │ │ │ │ ├── amazon-song-playlog.component.spec.ts │ │ │ │ └── amazon-song-playlog.component.ts │ │ │ │ ├── amazon-songlist │ │ │ │ ├── amazon-songlist.component.css │ │ │ │ ├── amazon-songlist.component.html │ │ │ │ ├── amazon-songlist.component.spec.ts │ │ │ │ └── amazon-songlist.component.ts │ │ │ │ ├── amazon.module.ts │ │ │ │ ├── amazon.routing.ts │ │ │ │ ├── chuni-music-db.service.ts │ │ │ │ ├── model │ │ │ │ ├── AmazonCharacter.ts │ │ │ │ ├── AmazonPlayLog.ts │ │ │ │ ├── AmazonProfile.ts │ │ │ │ ├── AmazonRecord.ts │ │ │ │ ├── ChuniCharacter.ts │ │ │ │ ├── ChuniMusic.ts │ │ │ │ └── ChuniSkill.ts │ │ │ │ └── util │ │ │ │ ├── cource-id-to-class.pipe.spec.ts │ │ │ │ ├── cource-id-to-class.pipe.ts │ │ │ │ ├── rating-class.pipe.ts │ │ │ │ ├── to-rank.pipe.spec.ts │ │ │ │ ├── to-rank.pipe.ts │ │ │ │ ├── to-rating.pipe.spec.ts │ │ │ │ └── to-rating.pipe.ts │ │ ├── diva │ │ │ ├── diva-customize │ │ │ │ ├── diva-customize.component.css │ │ │ │ ├── diva-customize.component.html │ │ │ │ ├── diva-customize.component.spec.ts │ │ │ │ └── diva-customize.component.ts │ │ │ ├── diva-management │ │ │ │ ├── diva-contest │ │ │ │ │ ├── diva-contest-edit │ │ │ │ │ │ ├── diva-contest-edit.component.css │ │ │ │ │ │ ├── diva-contest-edit.component.html │ │ │ │ │ │ ├── diva-contest-edit.component.spec.ts │ │ │ │ │ │ └── diva-contest-edit.component.ts │ │ │ │ │ ├── diva-contest.component.css │ │ │ │ │ ├── diva-contest.component.html │ │ │ │ │ ├── diva-contest.component.spec.ts │ │ │ │ │ ├── diva-contest.component.ts │ │ │ │ │ ├── diva-contest.service.spec.ts │ │ │ │ │ └── diva-contest.service.ts │ │ │ │ ├── diva-festa │ │ │ │ │ ├── diva-festa-edit │ │ │ │ │ │ ├── diva-festa-edit.component.css │ │ │ │ │ │ ├── diva-festa-edit.component.html │ │ │ │ │ │ ├── diva-festa-edit.component.spec.ts │ │ │ │ │ │ └── diva-festa-edit.component.ts │ │ │ │ │ ├── diva-festa.component.css │ │ │ │ │ ├── diva-festa.component.html │ │ │ │ │ ├── diva-festa.component.spec.ts │ │ │ │ │ ├── diva-festa.component.ts │ │ │ │ │ └── diva-festa.service.ts │ │ │ │ ├── diva-management │ │ │ │ │ ├── diva-management.component.css │ │ │ │ │ ├── diva-management.component.html │ │ │ │ │ ├── diva-management.component.spec.ts │ │ │ │ │ └── diva-management.component.ts │ │ │ │ └── diva-news │ │ │ │ │ ├── diva-news.component.css │ │ │ │ │ ├── diva-news.component.html │ │ │ │ │ ├── diva-news.component.spec.ts │ │ │ │ │ └── diva-news.component.ts │ │ │ ├── diva-modules │ │ │ │ ├── diva-modules.component.css │ │ │ │ ├── diva-modules.component.html │ │ │ │ ├── diva-modules.component.spec.ts │ │ │ │ └── diva-modules.component.ts │ │ │ ├── diva-mylist.service.ts │ │ │ ├── diva-profile │ │ │ │ ├── diva-profile.component.css │ │ │ │ ├── diva-profile.component.html │ │ │ │ ├── diva-profile.component.spec.ts │ │ │ │ └── diva-profile.component.ts │ │ │ ├── diva-pv-record │ │ │ │ ├── diva-pv-record.component.css │ │ │ │ ├── diva-pv-record.component.html │ │ │ │ ├── diva-pv-record.component.spec.ts │ │ │ │ └── diva-pv-record.component.ts │ │ │ ├── diva-pvlist │ │ │ │ ├── diva-pvlist.component.css │ │ │ │ ├── diva-pvlist.component.html │ │ │ │ ├── diva-pvlist.component.spec.ts │ │ │ │ └── diva-pvlist.component.ts │ │ │ ├── diva-recent │ │ │ │ ├── diva-recent.component.css │ │ │ │ ├── diva-recent.component.html │ │ │ │ ├── diva-recent.component.spec.ts │ │ │ │ └── diva-recent.component.ts │ │ │ ├── diva-record-detail │ │ │ │ ├── diva-record-detail.component.css │ │ │ │ ├── diva-record-detail.component.html │ │ │ │ ├── diva-record-detail.component.spec.ts │ │ │ │ └── diva-record-detail.component.ts │ │ │ ├── diva-setting │ │ │ │ ├── diva-display-setting │ │ │ │ │ ├── diva-display-setting.dialog.ts │ │ │ │ │ └── diva-display-setting.html │ │ │ │ ├── diva-mylist-setting │ │ │ │ │ ├── diva-mylist-setting.dialog.ts │ │ │ │ │ └── diva-mylist-setting.html │ │ │ │ ├── diva-name-setting │ │ │ │ │ ├── diva-name-setting.dialog.ts │ │ │ │ │ └── diva-name-setting.html │ │ │ │ ├── diva-plate-setting │ │ │ │ │ ├── diva-plate-setting.dialog.ts │ │ │ │ │ └── diva-plate-setting.html │ │ │ │ ├── diva-rival-setting │ │ │ │ │ ├── diva-rival-setting.dialog.ts │ │ │ │ │ └── diva-rival-setting.html │ │ │ │ ├── diva-se-setting │ │ │ │ │ ├── diva-se-setting.dialog.ts │ │ │ │ │ └── diva-se-setting.html │ │ │ │ ├── diva-setting.component.css │ │ │ │ ├── diva-setting.component.html │ │ │ │ ├── diva-setting.component.spec.ts │ │ │ │ ├── diva-setting.component.ts │ │ │ │ ├── diva-skin-setting │ │ │ │ │ ├── diva-skin-setting.dialog.ts │ │ │ │ │ └── diva-skin-setting.html │ │ │ │ └── diva-title-setting │ │ │ │ │ ├── diva-title-setting.dialog.ts │ │ │ │ │ └── diva-title-setting.html │ │ │ ├── diva.module.ts │ │ │ ├── diva.routing.ts │ │ │ ├── model │ │ │ │ ├── DivaCustomize.ts │ │ │ │ ├── DivaModule.ts │ │ │ │ ├── DivaPlayLog.ts │ │ │ │ ├── DivaProfile.ts │ │ │ │ ├── DivaPv.ts │ │ │ │ ├── DivaPvRecord.ts │ │ │ │ ├── DivaRankingRecord.ts │ │ │ │ ├── DivaRecordDetail.ts │ │ │ │ ├── Page.ts │ │ │ │ └── mannagement │ │ │ │ │ ├── Festa.ts │ │ │ │ │ └── contest.ts │ │ │ └── util │ │ │ │ └── diva-decimal.pipe.ts │ │ └── ongeki │ │ │ ├── model │ │ │ ├── OngekiCard.ts │ │ │ ├── OngekiCharacter.ts │ │ │ ├── OngekiEnums.ts │ │ │ ├── OngekiMusic.ts │ │ │ ├── OngekiProfile.ts │ │ │ ├── OngekiSkill.ts │ │ │ ├── PlayerCard.ts │ │ │ ├── PlayerPlaylog.ts │ │ │ └── PlayerRatingItem.ts │ │ │ ├── ongeki-battle-point │ │ │ ├── ongeki-battle-point.component.css │ │ │ ├── ongeki-battle-point.component.html │ │ │ ├── ongeki-battle-point.component.spec.ts │ │ │ └── ongeki-battle-point.component.ts │ │ │ ├── ongeki-card-gacha │ │ │ ├── ongeki-card-gacha.component.css │ │ │ ├── ongeki-card-gacha.component.html │ │ │ ├── ongeki-card-gacha.component.spec.ts │ │ │ └── ongeki-card-gacha.component.ts │ │ │ ├── ongeki-card-list │ │ │ ├── ongeki-card-list.component.css │ │ │ ├── ongeki-card-list.component.html │ │ │ ├── ongeki-card-list.component.spec.ts │ │ │ └── ongeki-card-list.component.ts │ │ │ ├── ongeki-card │ │ │ ├── ongeki-card.component.css │ │ │ ├── ongeki-card.component.html │ │ │ ├── ongeki-card.component.spec.ts │ │ │ └── ongeki-card.component.ts │ │ │ ├── ongeki-profile │ │ │ ├── ongeki-profile.component.css │ │ │ ├── ongeki-profile.component.html │ │ │ ├── ongeki-profile.component.spec.ts │ │ │ └── ongeki-profile.component.ts │ │ │ ├── ongeki-rating │ │ │ ├── ongeki-rating.component.css │ │ │ ├── ongeki-rating.component.html │ │ │ ├── ongeki-rating.component.spec.ts │ │ │ └── ongeki-rating.component.ts │ │ │ ├── ongeki-recent │ │ │ ├── ongeki-recent.component.css │ │ │ ├── ongeki-recent.component.html │ │ │ ├── ongeki-recent.component.spec.ts │ │ │ └── ongeki-recent.component.ts │ │ │ ├── ongeki-setting │ │ │ ├── ongeki-setting.component.css │ │ │ ├── ongeki-setting.component.html │ │ │ ├── ongeki-setting.component.spec.ts │ │ │ └── ongeki-setting.component.ts │ │ │ ├── ongeki-song-list │ │ │ ├── ongeki-song-list.component.css │ │ │ ├── ongeki-song-list.component.html │ │ │ ├── ongeki-song-list.component.spec.ts │ │ │ └── ongeki-song-list.component.ts │ │ │ ├── ongeki.module.ts │ │ │ ├── ongeki.routing.ts │ │ │ └── util │ │ │ ├── to-attribute-class.pipe.spec.ts │ │ │ ├── to-attribute-class.pipe.ts │ │ │ ├── to-battle-sprite.pipe.spec.ts │ │ │ ├── to-battle-sprite.pipe.ts │ │ │ ├── to-level-decimal.pipe.spec.ts │ │ │ ├── to-level-decimal.pipe.ts │ │ │ ├── to-tech-sprite.pipe.spec.ts │ │ │ └── to-tech-sprite.pipe.ts │ └── util │ │ ├── formatnumber.pipe.spec.ts │ │ ├── formatnumber.pipe.ts │ │ └── tools.module.ts ├── assets │ ├── .gitkeep │ └── icons │ │ ├── icon-128x128.png │ │ ├── icon-144x144.png │ │ ├── icon-152x152.png │ │ ├── icon-192x192.png │ │ ├── icon-384x384.png │ │ ├── icon-512x512.png │ │ ├── icon-72x72.png │ │ └── icon-96x96.png ├── environments │ ├── environment.prod.ts │ └── environment.ts ├── favicon.ico ├── index.html ├── main.ts ├── manifest.webmanifest ├── polyfills.ts ├── styles.css └── test.ts ├── tsconfig.app.json ├── tsconfig.base.json ├── tsconfig.json ├── tsconfig.spec.json └── tslint.json /.browserslistrc: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # You can see what browsers were selected by your queries by running: 6 | # npx browserslist 7 | 8 | > 0.5% 9 | last 2 versions 10 | Firefox ESR 11 | not dead 12 | not IE 9-11 # For IE 9-11 support, remove 'not'. -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | build: 10 | 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - uses: actions/checkout@v2 15 | - name: Setup Node 16 | uses: actions/setup-node@v1 17 | with: 18 | node-version: '12.x' 19 | - name: Install Dependencies 20 | run: npm install 21 | - name: Deploy 22 | env: 23 | CI: true 24 | GH_TOKEN: ${{ secrets.PERSONAL_TOKEN }} 25 | run: npm run deploy -- --cname "aqua.samnyan.icu" --name="samnyan" --email=4137880+samnyan@users.noreply.github.com 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | # Only exists if Bazel was run 8 | /bazel-out 9 | 10 | # dependencies 11 | /node_modules 12 | 13 | # profiling files 14 | chrome-profiler-events*.json 15 | speed-measure-plugin*.json 16 | 17 | # IDEs and editors 18 | /.idea 19 | .project 20 | .classpath 21 | .c9/ 22 | *.launch 23 | .settings/ 24 | *.sublime-workspace 25 | 26 | # IDE - VSCode 27 | .vscode/* 28 | !.vscode/settings.json 29 | !.vscode/tasks.json 30 | !.vscode/launch.json 31 | !.vscode/extensions.json 32 | .history/* 33 | 34 | # misc 35 | /.sass-cache 36 | /connect.lock 37 | /coverage 38 | /libpeerconnection.log 39 | npm-debug.log 40 | yarn-error.log 41 | testem.log 42 | /typings 43 | 44 | # System Files 45 | .DS_Store 46 | Thumbs.db 47 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AquaViewer 2 | 3 | A WebUI for AQUA Server 4 | 5 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 8.3.20. 6 | 7 | ## Live Version 8 | Go http://aqua.samnyan.icu/ 9 | 10 | Please notice that if you are using HTTPS, your browser may block HTTP connect to the game server. 11 | 12 | ## Self Host 13 | Go to [gh-pages branch](https://github.com/samnyan/aqua-viewer/tree/gh-pages), then clone all the file or download as zip. This build is up to date with the source. 14 | 15 | ###Build From Source 16 | You need to have Angular-cli installed and run `ng build --prod`. 17 | 18 | Please follow the [deployment guide](https://angular.io/guide/deployment) if you are new to angular. 19 | -------------------------------------------------------------------------------- /e2e/protractor.conf.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | // Protractor configuration file, see link for more information 3 | // https://github.com/angular/protractor/blob/master/lib/config.ts 4 | 5 | const {SpecReporter} = require('jasmine-spec-reporter'); 6 | 7 | /** 8 | * @type { import("protractor").Config } 9 | */ 10 | exports.config = { 11 | allScriptsTimeout: 11000, 12 | specs: [ 13 | './src/**/*.e2e-spec.ts' 14 | ], 15 | capabilities: { 16 | browserName: 'chrome' 17 | }, 18 | directConnect: true, 19 | baseUrl: 'http://localhost:4200/', 20 | framework: 'jasmine', 21 | jasmineNodeOpts: { 22 | showColors: true, 23 | defaultTimeoutInterval: 30000, 24 | print: function () { 25 | } 26 | }, 27 | onPrepare() { 28 | require('ts-node').register({ 29 | project: require('path').join(__dirname, './tsconfig.json') 30 | }); 31 | jasmine.getEnv().addReporter(new SpecReporter({spec: {displayStacktrace: true}})); 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /e2e/src/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import {AppPage} from './app.po'; 2 | import {browser, logging} from 'protractor'; 3 | 4 | describe('workspace-project App', () => { 5 | let page: AppPage; 6 | 7 | beforeEach(() => { 8 | page = new AppPage(); 9 | }); 10 | 11 | it('should display welcome message', () => { 12 | page.navigateTo(); 13 | expect(page.getTitleText()).toEqual('aqua-viewer app is running!'); 14 | }); 15 | 16 | afterEach(async () => { 17 | // Assert that there are no errors emitted from the browser 18 | const logs = await browser.manage().logs().get(logging.Type.BROWSER); 19 | expect(logs).not.toContain(jasmine.objectContaining({ 20 | level: logging.Level.SEVERE, 21 | } as logging.Entry)); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import {browser, by, element} from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo() { 5 | return browser.get(browser.baseUrl) as Promise; 6 | } 7 | 8 | getTitleText() { 9 | return element(by.css('app-root .content span')).getText() as Promise; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.base.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/e2e", 5 | "module": "commonjs", 6 | "target": "es2018", 7 | "types": [ 8 | "jasmine", 9 | "jasminewd2", 10 | "node" 11 | ] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | dir: require('path').join(__dirname, './coverage/aqua-viewer'), 20 | reports: ['html', 'lcovonly', 'text-summary'], 21 | fixWebpackSourcePaths: true 22 | }, 23 | reporters: ['progress', 'kjhtml'], 24 | port: 9876, 25 | colors: true, 26 | logLevel: config.LOG_INFO, 27 | autoWatch: true, 28 | browsers: ['Chrome'], 29 | singleRun: false, 30 | restartOnFileChange: true 31 | }); 32 | }; 33 | -------------------------------------------------------------------------------- /ngsw-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/service-worker/config/schema.json", 3 | "index": "/index.html", 4 | "assetGroups": [ 5 | { 6 | "name": "app", 7 | "installMode": "prefetch", 8 | "resources": { 9 | "files": [ 10 | "/favicon.ico", 11 | "/index.html", 12 | "/manifest.webmanifest", 13 | "/*.css", 14 | "/*.js" 15 | ] 16 | } 17 | }, 18 | { 19 | "name": "assets", 20 | "installMode": "lazy", 21 | "updateMode": "prefetch", 22 | "resources": { 23 | "files": [ 24 | "/assets/**", 25 | "/*.(eot|svg|cur|jpg|png|webp|gif|otf|ttf|woff|woff2|ani)" 26 | ] 27 | } 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aqua-viewer", 3 | "version": "0.0.1", 4 | "scripts": { 5 | "ng": "ng", 6 | "start": "ng serve --host 0.0.0.0", 7 | "http": "http-server -p 8080 -c-1 dist/aqua-viewer", 8 | "build": "ng build", 9 | "test": "ng test", 10 | "lint": "ng lint", 11 | "e2e": "ng e2e", 12 | "deploy": "ng deploy", 13 | "postinstall": "ngcc" 14 | }, 15 | "private": true, 16 | "dependencies": { 17 | "@angular/animations": "~10.0.5", 18 | "@angular/cdk": "~10.1.0", 19 | "@angular/common": "~10.0.5", 20 | "@angular/compiler": "~10.0.5", 21 | "@angular/core": "~10.0.5", 22 | "@angular/flex-layout": "^10.0.0-beta.32", 23 | "@angular/forms": "~10.0.5", 24 | "@angular/material": "^10.1.0", 25 | "@angular/platform-browser": "~10.0.5", 26 | "@angular/platform-browser-dynamic": "~10.0.5", 27 | "@angular/router": "~10.0.5", 28 | "@angular/service-worker": "~10.0.5", 29 | "@createjs/easeljs": "^2.0.0-beta.4", 30 | "@createjs/tweenjs": "^2.0.0-beta.4", 31 | "angular-cli-ghpages": "^0.6.2", 32 | "minimist": "^1.2.5", 33 | "ngx-indexed-db": "^5.0.5", 34 | "ngx-pagination": "^5.0.0", 35 | "rxjs": "~6.6.0", 36 | "tslib": "^2.0.0", 37 | "zone.js": "~0.10.3" 38 | }, 39 | "devDependencies": { 40 | "@angular-devkit/build-angular": "~0.1000.4", 41 | "@angular/cli": "~10.0.4", 42 | "@angular/compiler-cli": "~10.0.5", 43 | "@angular/language-service": "~10.0.5", 44 | "@types/jasmine": "~3.5.10", 45 | "@types/jasminewd2": "~2.0.8", 46 | "@types/node": "^12.12.31", 47 | "codelyzer": "^6.0.0", 48 | "http-server": "^0.12.3", 49 | "jasmine-core": "~3.5.0", 50 | "jasmine-spec-reporter": "~5.0.0", 51 | "karma": "~5.0.0", 52 | "karma-chrome-launcher": "~3.1.0", 53 | "karma-coverage-istanbul-reporter": "~3.0.2", 54 | "karma-jasmine": "~3.3.0", 55 | "karma-jasmine-html-reporter": "^1.5.0", 56 | "protractor": "~7.0.0", 57 | "ts-node": "~8.8.1", 58 | "tslint": "~6.1.0", 59 | "typescript": "^3.9.7" 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/app/api.service.ts: -------------------------------------------------------------------------------- 1 | import {HttpClient, HttpParams} from '@angular/common/http'; 2 | import {Injectable} from '@angular/core'; 3 | import {AuthenticationService} from './auth/authentication.service'; 4 | import {Subject} from 'rxjs'; 5 | 6 | @Injectable({ 7 | providedIn: 'root' 8 | }) 9 | export class ApiService { 10 | 11 | private loadingSubject = new Subject(); 12 | loadingState = this.loadingSubject.asObservable(); 13 | 14 | constructor(private http: HttpClient, 15 | private authenticationService: AuthenticationService) { 16 | } 17 | 18 | get(path: string, params?: HttpParams) { 19 | return this.http.get(this.getHost() + path, {params}); 20 | } 21 | 22 | post(path: string, data?: object, params?: HttpParams) { 23 | return this.http.post(this.getHost() + path, data, {params}); 24 | } 25 | 26 | put(path: string, data?: object, params?: HttpParams) { 27 | return this.http.put(this.getHost() + path, data, {params}); 28 | } 29 | 30 | delete(path: string, params?: HttpParams) { 31 | return this.http.delete(this.getHost() + path, {params}); 32 | } 33 | 34 | getHost(): string { 35 | if (this.authenticationService.currentUserValue) { 36 | return this.authenticationService.currentUserValue.apiServer + '/'; 37 | } 38 | return 'http://localhost:80' + '/'; 39 | } 40 | 41 | show() { 42 | this.loadingSubject.next({show: true}); 43 | } 44 | 45 | hide() { 46 | this.loadingSubject.next({show: false}); 47 | } 48 | 49 | } 50 | 51 | export class Resp { 52 | status: string; 53 | data: object; 54 | } 55 | 56 | export interface LoadingState { 57 | show: boolean; 58 | } 59 | -------------------------------------------------------------------------------- /src/app/app-routing.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {PreloadAllModules, RouterModule, Routes} from '@angular/router'; 3 | import {LoginComponent} from './login/login.component'; 4 | import {DashboardComponent} from './dashboard/dashboard.component'; 5 | import {AuthGuardService} from './auth/auth-guard.service'; 6 | import {ChangelogComponent} from './changelog/changelog.component'; 7 | import {ImporterComponent} from './importer/importer/importer.component'; 8 | 9 | const routes: Routes = [ 10 | {path: '', redirectTo: '/login', pathMatch: 'full'}, 11 | {path: 'login', component: LoginComponent}, 12 | {path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuardService]}, 13 | {path: 'changelog', component: ChangelogComponent}, 14 | {path: 'import', component: ImporterComponent}, 15 | {path: 'diva', loadChildren: () => import('./sega/diva/diva.module').then(mod => mod.DivaModule), canLoad: [AuthGuardService]}, 16 | {path: 'ongeki', loadChildren: () => import('./sega/ongeki/ongeki.module').then(mod => mod.OngekiModule), canLoad: [AuthGuardService]}, 17 | { 18 | path: 'amazon', 19 | loadChildren: () => import('./sega/chunithm/amazon/amazon.module').then(mod => mod.AmazonModule), 20 | canLoad: [AuthGuardService] 21 | }, 22 | ]; 23 | 24 | @NgModule({ 25 | imports: [RouterModule.forRoot(routes, {preloadingStrategy: PreloadAllModules})], 26 | exports: [RouterModule] 27 | }) 28 | 29 | export class AppRoutingModule { 30 | } 31 | -------------------------------------------------------------------------------- /src/app/app.component.css: -------------------------------------------------------------------------------- 1 | .container { 2 | display: flex; 3 | flex-direction: column; 4 | position: absolute; 5 | top: 0; 6 | bottom: 0; 7 | left: 0; 8 | right: 0; 9 | } 10 | 11 | .is-mobile .toolbar { 12 | position: fixed; 13 | z-index: 2; 14 | } 15 | 16 | .sidenav { 17 | flex: 1; 18 | height: auto; 19 | } 20 | 21 | mat-sidenav { 22 | min-width: 200px; 23 | } 24 | 25 | mat-toolbar { 26 | z-index: 999; 27 | } 28 | 29 | .content { 30 | background-origin: content-box; 31 | height: auto; 32 | overflow-y: visible; 33 | width: 92%; 34 | max-width: 1280px; 35 | box-sizing: border-box; 36 | padding: 30px; 37 | margin: auto; 38 | } 39 | 40 | .content .padding { 41 | padding-top: 4px; 42 | } 43 | 44 | .bg { 45 | transition-duration: .218s; 46 | transition-property: background; 47 | transition-timing-function: ease-in; 48 | } 49 | 50 | .dark { 51 | background-color: #202124; 52 | } 53 | 54 | .hide { 55 | display: none; 56 | } 57 | 58 | @media only screen and (max-width: 599px) { 59 | .content { 60 | background-origin: content-box; 61 | height: auto; 62 | overflow-y: visible; 63 | width: 96%; 64 | box-sizing: border-box; 65 | padding: 15px; 66 | margin: auto; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/app/app.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 6 | Aqua Viewer 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 22 | 23 | Dashboard 24 | Import 25 | 26 | O.N.G.E.K.I 27 | {{item.name}} 28 | 29 | Project DIVA AFT 30 | {{item.name}} 31 | 32 | CHUNITHM Amazon 33 | {{item.name}} 34 | 35 | 36 | 37 | 38 |
39 | 40 |
41 | 42 | 43 |
44 |
45 |
46 | -------------------------------------------------------------------------------- /src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import {async, TestBed} from '@angular/core/testing'; 2 | import {AppComponent} from './app.component'; 3 | 4 | describe('AppComponent', () => { 5 | beforeEach(async(() => { 6 | TestBed.configureTestingModule({ 7 | declarations: [ 8 | AppComponent 9 | ], 10 | }).compileComponents(); 11 | })); 12 | 13 | it('should create the app', () => { 14 | const fixture = TestBed.createComponent(AppComponent); 15 | const app = fixture.debugElement.componentInstance; 16 | expect(app).toBeTruthy(); 17 | }); 18 | 19 | it(`should have as title 'aqua-viewer'`, () => { 20 | const fixture = TestBed.createComponent(AppComponent); 21 | const app = fixture.debugElement.componentInstance; 22 | expect(app.title).toEqual('aqua-viewer'); 23 | }); 24 | 25 | it('should render title', () => { 26 | const fixture = TestBed.createComponent(AppComponent); 27 | fixture.detectChanges(); 28 | const compiled = fixture.debugElement.nativeElement; 29 | expect(compiled.querySelector('.content span').textContent).toContain('aqua-viewer app is running!'); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /src/app/auth/auth-guard.service.spec.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable:no-unused-variable */ 2 | 3 | import {inject, TestBed} from '@angular/core/testing'; 4 | import {AuthGuardService} from './auth-guard.service'; 5 | import {HttpClientModule} from '@angular/common/http'; 6 | import {RouterTestingModule} from '@angular/router/testing'; 7 | 8 | describe('Service: AuthGuard', () => { 9 | beforeEach(() => { 10 | TestBed.configureTestingModule({ 11 | imports: [ 12 | HttpClientModule, 13 | RouterTestingModule 14 | ], 15 | providers: [AuthGuardService] 16 | }); 17 | }); 18 | 19 | it('should ...', inject([AuthGuardService], (service: AuthGuardService) => { 20 | expect(service).toBeTruthy(); 21 | })); 22 | }); 23 | -------------------------------------------------------------------------------- /src/app/auth/auth-guard.service.ts: -------------------------------------------------------------------------------- 1 | import {AuthenticationService} from './authentication.service'; 2 | import {Injectable} from '@angular/core'; 3 | import {ActivatedRouteSnapshot, Router, RouterStateSnapshot} from '@angular/router'; 4 | import {Route} from '@angular/compiler/src/core'; 5 | 6 | @Injectable({ 7 | providedIn: 'root' 8 | }) 9 | export class AuthGuardService { 10 | 11 | constructor( 12 | private router: Router, 13 | private authenticationService: AuthenticationService 14 | ) { 15 | } 16 | 17 | canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { 18 | const currentUser = this.authenticationService.currentUserValue; 19 | if (currentUser) { 20 | return true; 21 | } 22 | 23 | this.router.navigate(['/login']); 24 | return false; 25 | } 26 | 27 | canLoad(route: Route) { 28 | const currentUser = this.authenticationService.currentUserValue; 29 | if (currentUser) { 30 | return true; 31 | } 32 | 33 | this.router.navigate(['/login']); 34 | return false; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/app/auth/authentication.service.spec.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable:no-unused-variable */ 2 | 3 | import {inject, TestBed} from '@angular/core/testing'; 4 | import {AuthenticationService} from './authentication.service'; 5 | import {HttpClientModule} from '@angular/common/http'; 6 | 7 | describe('Service: Authentication', () => { 8 | beforeEach(() => { 9 | TestBed.configureTestingModule({ 10 | imports: [HttpClientModule], 11 | providers: [AuthenticationService] 12 | }); 13 | }); 14 | 15 | it('should ...', inject([AuthenticationService], (service: AuthenticationService) => { 16 | expect(service).toBeTruthy(); 17 | })); 18 | }); 19 | -------------------------------------------------------------------------------- /src/app/auth/authentication.service.ts: -------------------------------------------------------------------------------- 1 | import {BehaviorSubject, Observable} from 'rxjs'; 2 | import {Injectable} from '@angular/core'; 3 | import {HttpClient} from '@angular/common/http'; 4 | import {map} from 'rxjs/operators'; 5 | 6 | @Injectable({ 7 | providedIn: 'root' 8 | }) 9 | export class AuthenticationService { 10 | public currentUser: Observable; 11 | private currentUserSubject: BehaviorSubject; 12 | 13 | constructor(private http: HttpClient) { 14 | this.currentUserSubject = new BehaviorSubject(JSON.parse(localStorage.getItem('currentUser'))); 15 | this.currentUser = this.currentUserSubject.asObservable(); 16 | } 17 | 18 | public get currentUserValue(): User { 19 | return this.currentUserSubject.value; 20 | } 21 | 22 | login(accessCode: string, server: string) { 23 | return this.http.post(server + '/' + 'api/sega/aime/getByAccessCode', {accessCode}) 24 | .pipe( 25 | map( 26 | resp => { 27 | if (resp && resp.extId) { 28 | const user = new User(resp.extId, server); 29 | localStorage.setItem('currentUser', JSON.stringify(user)); 30 | this.currentUserSubject.next(user); 31 | return user; 32 | } 33 | } 34 | ) 35 | ); 36 | } 37 | 38 | logout() { 39 | localStorage.removeItem('currentUser'); 40 | this.currentUserSubject.next(null); 41 | } 42 | 43 | } 44 | 45 | export class User { 46 | extId: number; 47 | apiServer: string; 48 | 49 | constructor(extId: number, apiServer: string) { 50 | this.extId = extId; 51 | this.apiServer = apiServer; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/app/auth/error-interceptor.service.spec.ts: -------------------------------------------------------------------------------- 1 | import {TestBed} from '@angular/core/testing'; 2 | 3 | import {ErrorInterceptorService} from './error-interceptor.service'; 4 | 5 | describe('ErrorInterceptorService', () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it('should be created', () => { 9 | const service: ErrorInterceptorService = TestBed.get(ErrorInterceptorService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /src/app/auth/error-interceptor.service.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from '@angular/core'; 2 | import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http'; 3 | import {Observable, throwError} from 'rxjs'; 4 | import {catchError} from 'rxjs/operators'; 5 | 6 | @Injectable({ 7 | providedIn: 'root' 8 | }) 9 | export class ErrorInterceptorService implements HttpInterceptor { 10 | 11 | constructor() { 12 | } 13 | 14 | intercept(request: HttpRequest, next: HttpHandler): Observable> { 15 | return next.handle(request).pipe(catchError(err => { 16 | console.log(err); 17 | const error = err.error ? err.error.message : err.status + err.statusText; 18 | return throwError(error); 19 | })); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/app/auth/loading-interceptor.service.spec.ts: -------------------------------------------------------------------------------- 1 | import {TestBed} from '@angular/core/testing'; 2 | 3 | import {LoadingInterceptorService} from './loading-interceptor.service'; 4 | 5 | describe('LoadingInterceptorService', () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it('should be created', () => { 9 | const service: LoadingInterceptorService = TestBed.get(LoadingInterceptorService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /src/app/auth/loading-interceptor.service.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from '@angular/core'; 2 | import {ApiService} from '../api.service'; 3 | import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse} from '@angular/common/http'; 4 | import {Observable} from 'rxjs'; 5 | import {tap} from 'rxjs/operators'; 6 | 7 | @Injectable({ 8 | providedIn: 'root' 9 | }) 10 | export class LoadingInterceptorService implements HttpInterceptor { 11 | 12 | constructor(private api: ApiService) { 13 | } 14 | 15 | intercept(req: HttpRequest, next: HttpHandler): Observable> { 16 | this.showLoader(); 17 | return next.handle(req).pipe(tap((event: HttpEvent) => { 18 | if (event instanceof HttpResponse) { 19 | this.onEnd(); 20 | } 21 | }, 22 | (err: any) => { 23 | this.onEnd(); 24 | })); 25 | } 26 | 27 | private onEnd(): void { 28 | this.hideLoader(); 29 | } 30 | 31 | private showLoader(): void { 32 | this.api.show(); 33 | } 34 | 35 | private hideLoader(): void { 36 | this.api.hide(); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/app/changelog/changelog.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samnyan/aqua-viewer/a718036ab6baa92d9aa469a9997b3c73e6d9bb1d/src/app/changelog/changelog.component.css -------------------------------------------------------------------------------- /src/app/changelog/changelog.component.html: -------------------------------------------------------------------------------- 1 | 2 | Changelog 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/app/changelog/changelog.component.spec.ts: -------------------------------------------------------------------------------- 1 | import {async, ComponentFixture, TestBed} from '@angular/core/testing'; 2 | 3 | import {ChangelogComponent} from './changelog.component'; 4 | 5 | describe('ChangelogComponent', () => { 6 | let component: ChangelogComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ChangelogComponent] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ChangelogComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/changelog/changelog.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-changelog', 5 | templateUrl: './changelog.component.html', 6 | styleUrls: ['./changelog.component.css'] 7 | }) 8 | export class ChangelogComponent implements OnInit { 9 | 10 | constructor() { 11 | } 12 | 13 | ngOnInit() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/app/dashboard/dashboard.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samnyan/aqua-viewer/a718036ab6baa92d9aa469a9997b3c73e6d9bb1d/src/app/dashboard/dashboard.component.css -------------------------------------------------------------------------------- /src/app/dashboard/dashboard.component.html: -------------------------------------------------------------------------------- 1 |

2 | Welcome to Aqua Server WebUI
3 | This version work with Aqua server v0.0.13 4 |

5 | 6 | 7 | Data Info 8 | 9 | Diva Music List : {{divaPv}}
10 | Diva Module List : {{divaPv}}
11 | Diva Customize List : {{divaPv}}
12 | Chunithm Music List : {{chuniMusic}}
13 | Chunithm Character List : {{chuniCharacter}}
14 | Chunithm Skill List : {{chuniSkill}}
15 | Ongeki Card List : {{ongekiCard}}
16 | Ongeki Character List : {{ongekiCharacter}}
17 | Ongeki Music List : {{ongekiMusic}}
18 | Ongeki Skill List : {{ongekiSkill}} 19 |
20 | 21 | 22 | 23 |
24 | -------------------------------------------------------------------------------- /src/app/dashboard/dashboard.component.spec.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable:no-unused-variable */ 2 | import {async, ComponentFixture, TestBed} from '@angular/core/testing'; 3 | 4 | import {DashboardComponent} from './dashboard.component'; 5 | 6 | describe('DashboardComponent', () => { 7 | let component: DashboardComponent; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(async(() => { 11 | TestBed.configureTestingModule({ 12 | declarations: [DashboardComponent] 13 | }) 14 | .compileComponents(); 15 | })); 16 | 17 | beforeEach(() => { 18 | fixture = TestBed.createComponent(DashboardComponent); 19 | component = fixture.componentInstance; 20 | fixture.detectChanges(); 21 | }); 22 | 23 | it('should create', () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /src/app/dashboard/dashboard.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | import {PreloadService} from '../database/preload.service'; 3 | import {NgxIndexedDBService} from 'ngx-indexed-db'; 4 | 5 | @Component({ 6 | selector: 'app-dashboard', 7 | templateUrl: './dashboard.component.html', 8 | styleUrls: ['./dashboard.component.css'] 9 | }) 10 | export class DashboardComponent implements OnInit { 11 | 12 | divaPv = 'Initialize'; 13 | divaModule = 'Initialize'; 14 | divaCustomize = 'Initialize'; 15 | chuniMusic = 'Initialize'; 16 | ongekiCard = 'Initialize'; 17 | ongekiCharacter = 'Initialize'; 18 | ongekiMusic = 'Initialize'; 19 | ongekiSkill = 'Initialize'; 20 | chuniCharacter = 'Initialize'; 21 | chuniSkill = 'Initialize'; 22 | 23 | constructor( 24 | private dbService: NgxIndexedDBService, 25 | private preload: PreloadService 26 | ) { 27 | } 28 | 29 | ngOnInit() { 30 | this.preload.divaPvState.subscribe(data => this.divaPv = data); 31 | this.preload.divaModuleState.subscribe(data => this.divaModule = data); 32 | this.preload.divaCustomizeState.subscribe(data => this.divaCustomize = data); 33 | this.preload.chuniMusicState.subscribe(data => this.chuniMusic = data); 34 | this.preload.ongekiCardState.subscribe(data => this.ongekiCard = data); 35 | this.preload.ongekiCharacterState.subscribe(data => this.ongekiCharacter = data); 36 | this.preload.ongekiMusicState.subscribe(data => this.ongekiMusic = data); 37 | this.preload.ongekiSkillState.subscribe(data => this.ongekiSkill = data); 38 | this.preload.chuniCharacterState.subscribe(data => this.chuniCharacter = data); 39 | this.preload.chuniSkillState.subscribe(data => this.chuniSkill = data); 40 | } 41 | 42 | reload() { 43 | this.preload.reload(); 44 | this.dbService.deleteDatabase().then( 45 | () => window.location.reload() 46 | ); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/app/dashboard/dashboard.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | 3 | import {DashboardComponent} from './dashboard.component'; 4 | import {MatButtonModule} from '@angular/material/button'; 5 | import {MatCardModule} from '@angular/material/card'; 6 | 7 | @NgModule({ 8 | imports: [ 9 | MatCardModule, 10 | MatButtonModule 11 | ], 12 | exports: [], 13 | declarations: [DashboardComponent], 14 | providers: [], 15 | }) 16 | export class DashboardModule { 17 | } 18 | -------------------------------------------------------------------------------- /src/app/database/preload.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { PreloadService } from './preload.service'; 4 | 5 | describe('PreloadService', () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it('should be created', () => { 9 | const service: PreloadService = TestBed.get(PreloadService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /src/app/importer/importer.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {CommonModule} from '@angular/common'; 3 | import {ImporterComponent} from './importer/importer.component'; 4 | import {MatCardModule} from '@angular/material/card'; 5 | import {MatButtonModule} from '@angular/material/button'; 6 | import {MatInputModule} from '@angular/material/input'; 7 | import {FormsModule, ReactiveFormsModule} from '@angular/forms'; 8 | 9 | 10 | @NgModule({ 11 | declarations: [ImporterComponent], 12 | imports: [ 13 | CommonModule, 14 | MatButtonModule, 15 | MatInputModule, 16 | MatCardModule, 17 | ReactiveFormsModule, 18 | FormsModule, 19 | ] 20 | }) 21 | export class ImporterModule { 22 | } 23 | -------------------------------------------------------------------------------- /src/app/importer/importer/importer.component.css: -------------------------------------------------------------------------------- 1 | .upload-button::-webkit-file-upload-button { 2 | visibility: hidden; 3 | } 4 | 5 | .upload-button::before { 6 | content: 'Select File'; 7 | cursor: pointer; 8 | outline: none; 9 | border: none; 10 | -webkit-tap-highlight-color: transparent; 11 | display: inline-block; 12 | white-space: nowrap; 13 | text-decoration: none; 14 | vertical-align: baseline; 15 | text-align: center; 16 | margin: 0; 17 | min-width: 64px; 18 | line-height: 36px; 19 | padding: 0 16px; 20 | border-radius: 4px; 21 | overflow: visible; 22 | background-color: #595959; 23 | } 24 | -------------------------------------------------------------------------------- /src/app/importer/importer/importer.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Import Data 4 | 5 | 6 | 7 | API Server 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | CHUNITHM 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | ONGEKI 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/app/importer/importer/importer.component.spec.ts: -------------------------------------------------------------------------------- 1 | import {async, ComponentFixture, TestBed} from '@angular/core/testing'; 2 | 3 | import {ImporterComponent} from './importer.component'; 4 | 5 | describe('ImporterComponent', () => { 6 | let component: ImporterComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ImporterComponent] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ImporterComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/importer/importer/importer.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | import {MessageService} from '../../message.service'; 3 | import {HttpClient} from '@angular/common/http'; 4 | import {AuthenticationService} from '../../auth/authentication.service'; 5 | 6 | @Component({ 7 | selector: 'app-importer', 8 | templateUrl: './importer.component.html', 9 | styleUrls: ['./importer.component.css'] 10 | }) 11 | export class ImporterComponent implements OnInit { 12 | 13 | apiServer: string; 14 | 15 | constructor( 16 | private http: HttpClient, 17 | private messageService: MessageService, 18 | private authenticationService: AuthenticationService 19 | ) { 20 | } 21 | 22 | ngOnInit(): void { 23 | if (this.authenticationService.currentUserValue) { 24 | this.apiServer = this.authenticationService.currentUserValue.apiServer; 25 | } else { 26 | this.apiServer = 'http://localhost:80'; 27 | } 28 | } 29 | 30 | chunithm(event) { 31 | this.uploadDocument(event.target.files[0], 'api/game/chuni/amazon/import', 'SDBT'); 32 | } 33 | 34 | ongeki(event) { 35 | this.uploadDocument(event.target.files[0], 'api/game/ongeki/import', 'SDDT'); 36 | } 37 | 38 | uploadDocument(file: File, path: string, type: string) { 39 | const fileReader = new FileReader(); 40 | fileReader.onload = (e) => { 41 | const j = JSON.parse(fileReader.result.toString()); 42 | console.log(j); 43 | if (j.gameId === type) { 44 | this.http.post(this.apiServer + '/' + path, j).subscribe( 45 | data => this.messageService.notice('OK'), 46 | error => this.messageService.notice(error) 47 | ); 48 | } else { 49 | this.messageService.notice('Wrong Game ID, please check you have select the correct file.'); 50 | } 51 | }; 52 | fileReader.readAsText(file); 53 | this.messageService.notice('Uploading...'); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/app/login/login.component.css: -------------------------------------------------------------------------------- 1 | .full-width { 2 | width: 100%; 3 | } 4 | 5 | .login-card { 6 | min-width: 120px; 7 | } 8 | -------------------------------------------------------------------------------- /src/app/login/login.component.html: -------------------------------------------------------------------------------- 1 | 20 | -------------------------------------------------------------------------------- /src/app/login/login.component.spec.ts: -------------------------------------------------------------------------------- 1 | import {async, ComponentFixture, TestBed} from '@angular/core/testing'; 2 | import {FormsModule, ReactiveFormsModule} from '@angular/forms'; 3 | import {MatButtonModule} from '@angular/material/button'; 4 | import {MatCardModule} from '@angular/material/card'; 5 | import {MatInputModule} from '@angular/material/input'; 6 | 7 | import {LoginComponent} from './login.component'; 8 | import {AppRoutingModule} from '../app-routing.module'; 9 | import {LayoutModule} from '@angular/cdk/layout'; 10 | import {DashboardModule} from '../dashboard/dashboard.module'; 11 | import {HttpClientModule} from '@angular/common/http'; 12 | 13 | describe('LoginComponent', () => { 14 | let component: LoginComponent; 15 | let fixture: ComponentFixture; 16 | 17 | beforeEach(async(() => { 18 | TestBed.configureTestingModule({ 19 | declarations: [LoginComponent], 20 | imports: [ 21 | LayoutModule, 22 | FormsModule, 23 | AppRoutingModule, 24 | 25 | HttpClientModule, 26 | DashboardModule, 27 | ReactiveFormsModule, 28 | MatButtonModule, 29 | MatInputModule, 30 | MatCardModule, 31 | ] 32 | }).compileComponents(); 33 | })); 34 | 35 | beforeEach(() => { 36 | fixture = TestBed.createComponent(LoginComponent); 37 | component = fixture.componentInstance; 38 | fixture.detectChanges(); 39 | }); 40 | 41 | it('should compile', () => { 42 | expect(component).toBeTruthy(); 43 | }); 44 | 45 | it(`form should be invalid`, async(() => { 46 | component.loginForm.controls.email.setValue(''); 47 | component.loginForm.controls.password.setValue(''); 48 | expect(component.loginForm.invalid).toBeTruthy(); 49 | })); 50 | 51 | it(`form should be valid`, async(() => { 52 | component.loginForm.controls.email.setValue('test@eamil.com'); 53 | component.loginForm.controls.password.setValue('12345'); 54 | expect(component.loginForm.invalid).toBeFalsy(); 55 | })); 56 | }); 57 | -------------------------------------------------------------------------------- /src/app/login/login.component.ts: -------------------------------------------------------------------------------- 1 | import {Router} from '@angular/router'; 2 | import {AuthenticationService} from '../auth/authentication.service'; 3 | import {Component, OnInit} from '@angular/core'; 4 | import {FormBuilder, FormGroup, Validators} from '@angular/forms'; 5 | import {MessageService} from '../message.service'; 6 | import {first} from 'rxjs/operators'; 7 | 8 | @Component({ 9 | selector: 'app-login', 10 | templateUrl: './login.component.html', 11 | styleUrls: ['./login.component.css'] 12 | }) 13 | export class LoginComponent implements OnInit { 14 | loginForm: FormGroup; 15 | 16 | 17 | constructor( 18 | private fb: FormBuilder, 19 | private router: Router, 20 | private authenticationService: AuthenticationService, 21 | private messageService: MessageService 22 | ) { 23 | } 24 | 25 | get f() { 26 | return this.loginForm.controls; 27 | } 28 | 29 | ngOnInit() { 30 | this.loginForm = this.fb.group({ 31 | accessCode: ['', Validators.required], 32 | apiServer: ['http://localhost:80', Validators.required], 33 | }); 34 | if (this.authenticationService.currentUserValue) { 35 | this.router.navigateByUrl('/dashboard'); 36 | } 37 | } 38 | 39 | onSubmit() { 40 | if (this.loginForm.invalid) { 41 | return; 42 | } 43 | 44 | let server: string = this.f.apiServer.value; 45 | if (!server.startsWith('http')) { 46 | server = 'http://' + server; 47 | } 48 | 49 | if (server.endsWith('/')) { 50 | server = server.substring(0, server.length - 1); 51 | } 52 | 53 | this.authenticationService.login(this.f.accessCode.value, server).pipe(first()) 54 | .subscribe( 55 | data => { 56 | if (data != null) { 57 | this.messageService.notice('OK'); 58 | location.reload(true); 59 | } else { 60 | this.messageService.notice('No such Card'); 61 | } 62 | }, 63 | error => { 64 | this.messageService.notice(error.message); 65 | console.warn('login fail', error); 66 | } 67 | ); 68 | 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/app/login/login.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | 3 | import {LoginComponent} from './login.component'; 4 | import {LayoutModule} from '@angular/cdk/layout'; 5 | import {FormsModule, ReactiveFormsModule} from '@angular/forms'; 6 | import {AppRoutingModule} from '../app-routing.module'; 7 | import {MatButtonModule} from '@angular/material/button'; 8 | import {MatInputModule} from '@angular/material/input'; 9 | import {MatCardModule} from '@angular/material/card'; 10 | 11 | @NgModule({ 12 | imports: [ 13 | LayoutModule, 14 | FormsModule, 15 | AppRoutingModule, 16 | 17 | ReactiveFormsModule, 18 | MatButtonModule, 19 | MatInputModule, 20 | MatCardModule, 21 | ], 22 | exports: [], 23 | declarations: [LoginComponent], 24 | providers: [], 25 | }) 26 | export class LoginModule { 27 | } 28 | -------------------------------------------------------------------------------- /src/app/message.service.ts: -------------------------------------------------------------------------------- 1 | import {MessageComponent} from './message/message.component'; 2 | import {Injectable} from '@angular/core'; 3 | 4 | @Injectable({ 5 | providedIn: 'root' 6 | }) 7 | export class MessageService { 8 | constructor(private messageComponent: MessageComponent) { 9 | } 10 | 11 | notice(message: string) { 12 | this.messageComponent.openSnackBar(message); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/app/message/message.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samnyan/aqua-viewer/a718036ab6baa92d9aa469a9997b3c73e6d9bb1d/src/app/message/message.component.css -------------------------------------------------------------------------------- /src/app/message/message.component.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samnyan/aqua-viewer/a718036ab6baa92d9aa469a9997b3c73e6d9bb1d/src/app/message/message.component.html -------------------------------------------------------------------------------- /src/app/message/message.component.spec.ts: -------------------------------------------------------------------------------- 1 | import {BrowserAnimationsModule} from '@angular/platform-browser/animations'; 2 | import {MessageModule} from './message.module'; 3 | /* tslint:disable:no-unused-variable */ 4 | import {async, ComponentFixture, TestBed} from '@angular/core/testing'; 5 | 6 | import {MessageComponent} from './message.component'; 7 | 8 | describe('MessageComponent', () => { 9 | let component: MessageComponent; 10 | let fixture: ComponentFixture; 11 | 12 | beforeEach(async(() => { 13 | TestBed.configureTestingModule({ 14 | imports: [ 15 | MessageModule, 16 | BrowserAnimationsModule, 17 | ] 18 | }) 19 | .compileComponents(); 20 | })); 21 | 22 | beforeEach(() => { 23 | fixture = TestBed.createComponent(MessageComponent); 24 | component = fixture.componentInstance; 25 | fixture.detectChanges(); 26 | }); 27 | 28 | it('should create', () => { 29 | expect(component).toBeTruthy(); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /src/app/message/message.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, Injectable, OnInit} from '@angular/core'; 2 | import {MatSnackBar} from '@angular/material/snack-bar'; 3 | 4 | @Injectable({ 5 | providedIn: 'root' 6 | }) 7 | @Component({ 8 | selector: 'app-message', 9 | templateUrl: './message.component.html', 10 | styleUrls: ['./message.component.css'] 11 | }) 12 | export class MessageComponent implements OnInit { 13 | 14 | 15 | constructor( 16 | private _snackBar: MatSnackBar 17 | ) { 18 | } 19 | 20 | 21 | ngOnInit() { 22 | this.openSnackBar('Initialized'); 23 | } 24 | 25 | public openSnackBar(message: string) { 26 | this._snackBar.open(message, 'OK', { 27 | duration: 2000, 28 | }); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/app/message/message.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | 3 | import {MessageComponent} from './message.component'; 4 | import {MatSnackBarModule} from '@angular/material/snack-bar'; 5 | import {MatButtonModule} from '@angular/material/button'; 6 | 7 | @NgModule({ 8 | imports: [ 9 | MatSnackBarModule, 10 | MatButtonModule 11 | ], 12 | exports: [MessageComponent], 13 | declarations: [MessageComponent], 14 | providers: [], 15 | }) 16 | export class MessageModule { 17 | } 18 | -------------------------------------------------------------------------------- /src/app/model/Page.ts: -------------------------------------------------------------------------------- 1 | export interface Page { 2 | content: T; 3 | page: number; 4 | totalPages: number; 5 | totalElements: number; 6 | } 7 | -------------------------------------------------------------------------------- /src/app/model/PropertyEntry.ts: -------------------------------------------------------------------------------- 1 | export interface PropertyEntry { 2 | propertyKey: string; 3 | propertyValue: string; 4 | } 5 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/amazon-character/amazon-character.component.css: -------------------------------------------------------------------------------- 1 | .character-display { 2 | display: flex; 3 | } 4 | 5 | .character-display .image { 6 | max-width: 30%; 7 | } 8 | 9 | .character-display .image img { 10 | width: 100%; 11 | } 12 | 13 | .character-display .content { 14 | margin: 0 auto; 15 | width: 65%; 16 | } 17 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/amazon-character/amazon-character.component.html: -------------------------------------------------------------------------------- 1 | 2 | Characters 3 | 4 | 5 | 6 | 7 | 8 | 10 | 11 | {{item.characterInfo ? item.characterInfo.name : 'ID:' + item.characterId}} 12 | 13 | 14 |
15 |
16 | 18 | 19 | 20 |
21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 39 | 40 |
Level{{item.level}}
Friendship Exp{{item.friendshipExp}}
Play Count{{item.playCount}}
Skill{{item.skillInfo ? item.skillInfo.name : 'SkillId: ' + item.skillId}}
38 | {{item.skillInfo ? item.skillInfo.category : ''}}
41 |
42 |
43 |
44 | 45 |
46 | 50 |
51 |
52 | 55 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/amazon-character/amazon-character.component.spec.ts: -------------------------------------------------------------------------------- 1 | import {async, ComponentFixture, TestBed} from '@angular/core/testing'; 2 | 3 | import {AmazonCharacterComponent} from './amazon-character.component'; 4 | 5 | describe('AmazonCharacterComponent', () => { 6 | let component: AmazonCharacterComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [AmazonCharacterComponent] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(AmazonCharacterComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/amazon-profile/amazon-profile.component.css: -------------------------------------------------------------------------------- 1 | /*mat-card {*/ 2 | /* background-image: url("https://i.loli.net/2019/11/25/Xv4M5Npl9wib3Em.png");*/ 3 | /* background-repeat: no-repeat;*/ 4 | /* background-position: right top;*/ 5 | /* background-size: 50%;*/ 6 | /*}*/ 7 | 8 | mat-card-content { 9 | font-size: 18px; 10 | line-height: 1.5rem; 11 | } 12 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/amazon-profile/amazon-profile.component.html: -------------------------------------------------------------------------------- 1 | 2 | Player Profile 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 |
Player Name{{profile.userName}}
Player Rating{{profile.playerRating / 100}}
Player Highest Rating{{profile.highestRating / 100}}
Player Level{{profile.level}}
Total Play Count{{profile.playCount}}
Name Plate Id{{profile.nameplateId}}
Frame Id{{profile.frameId}}
Character Id{{profile.characterId}}
Last Play{{profile.lastPlayDate}}
Total High Score{{profile.totalHiScore}}
Total Basic High Score{{profile.totalBasicHighScore}}
Total Advanced High Score{{profile.totalAdvancedHighScore}}
Total Expert High Score{{profile.totalExpertHighScore}}
Total Master High Score{{profile.totalMasterHighScore}}
62 |
63 |
64 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/amazon-profile/amazon-profile.component.spec.ts: -------------------------------------------------------------------------------- 1 | import {async, ComponentFixture, TestBed} from '@angular/core/testing'; 2 | 3 | import {AmazonProfileComponent} from './amazon-profile.component'; 4 | 5 | describe('AmazonProfileComponent', () => { 6 | let component: AmazonProfileComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [AmazonProfileComponent] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(AmazonProfileComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/amazon-rating/amazon-rating.component.css: -------------------------------------------------------------------------------- 1 | 2 | .skill-card table { 3 | width: 100%; 4 | font-size: 16px; 5 | } 6 | 7 | .skill-card h3 { 8 | font-size: 20px; 9 | text-align: center; 10 | } 11 | 12 | .skill-card img { 13 | width: 18px; 14 | height: 18px; 15 | padding: 0; 16 | } 17 | 18 | td { 19 | max-width: 130px; 20 | } 21 | 22 | thead th { 23 | text-align: center; 24 | } 25 | 26 | tr * { 27 | padding: 10px 0; 28 | } 29 | 30 | @media only screen and (max-width: 599px) { 31 | .skill-card table { 32 | width: 100%; 33 | font-size: 12px; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/amazon-rating/amazon-rating.component.spec.ts: -------------------------------------------------------------------------------- 1 | import {async, ComponentFixture, TestBed} from '@angular/core/testing'; 2 | 3 | import {AmazonRatingComponent} from './amazon-rating.component'; 4 | 5 | describe('AmazonRatingComponent', () => { 6 | let component: AmazonRatingComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [AmazonRatingComponent] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(AmazonRatingComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/amazon-rating/amazon-rating.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | import {MessageService} from '../../../../message.service'; 3 | import {ApiService} from '../../../../api.service'; 4 | import {HttpParams} from '@angular/common/http'; 5 | import {AuthenticationService} from '../../../../auth/authentication.service'; 6 | import {environment} from '../../../../../environments/environment'; 7 | 8 | @Component({ 9 | selector: 'app-amazon-rating', 10 | templateUrl: './amazon-rating.component.html', 11 | styleUrls: ['./amazon-rating.component.css'] 12 | }) 13 | export class AmazonRatingComponent implements OnInit { 14 | 15 | host = environment.assetsHost; 16 | 17 | topRating: RatingItem[] = []; 18 | recentRating: RatingItem[] = []; 19 | topTotal = 0; 20 | recentTotal = 0; 21 | 22 | constructor( 23 | private api: ApiService, 24 | private auth: AuthenticationService, 25 | private messageService: MessageService 26 | ) { 27 | } 28 | 29 | ngOnInit() { 30 | const aimeId = String(this.auth.currentUserValue.extId); 31 | const param = new HttpParams().set('aimeId', aimeId); 32 | this.api.get('api/game/chuni/amazon/rating', param).subscribe( 33 | data => { 34 | this.topRating = data; 35 | if (this.topRating.length === 0) { 36 | this.messageService.notice('No Data'); 37 | } 38 | this.topRating.forEach(item => this.topTotal += item.rating); 39 | }, 40 | error => this.messageService.notice(error) 41 | ); 42 | 43 | this.api.get('api/game/chuni/amazon/rating/recent', param).subscribe( 44 | data => { 45 | this.recentRating = data; 46 | if (this.recentRating.length === 0) { 47 | this.messageService.notice('No Data'); 48 | } 49 | this.recentRating.forEach(item => this.recentTotal += item.rating); 50 | }, 51 | error => this.messageService.notice(error) 52 | ); 53 | } 54 | 55 | } 56 | 57 | export interface RatingItem { 58 | musicId: number; 59 | musicName: string; 60 | artistName: string; 61 | level: number; 62 | score: number; 63 | ratingBase: number; 64 | rating: number; 65 | } 66 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/amazon-recent/amazon-recent.component.css: -------------------------------------------------------------------------------- 1 | .record mat-card-title { 2 | font-size: 1.2em; 3 | text-align: right; 4 | } 5 | 6 | .song-header { 7 | display: flex; 8 | } 9 | 10 | .song-header img { 11 | width: 42px; 12 | height: 42px; 13 | } 14 | 15 | .song-header .level { 16 | margin-left: auto; 17 | font-size: 1.2em; 18 | } 19 | 20 | .song-info { 21 | margin-left: 4px; 22 | } 23 | 24 | .song-info .title { 25 | font-size: 1.2em; 26 | } 27 | 28 | .song-info .info { 29 | color: #cfcfcf; 30 | } 31 | 32 | .result-content { 33 | display: flex; 34 | } 35 | 36 | .result-content .left { 37 | min-width: 30%; 38 | text-align: center; 39 | margin: auto; 40 | } 41 | 42 | .result-content .right { 43 | width: 100%; 44 | } 45 | 46 | .achievement-value { 47 | font-size: 1.5rem; 48 | } 49 | 50 | .score-value { 51 | font-size: 1.4rem; 52 | } 53 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/amazon-recent/amazon-recent.component.spec.ts: -------------------------------------------------------------------------------- 1 | import {async, ComponentFixture, TestBed} from '@angular/core/testing'; 2 | 3 | import {AmazonRecentComponent} from './amazon-recent.component'; 4 | 5 | describe('AmazonRecentComponent', () => { 6 | let component: AmazonRecentComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [AmazonRecentComponent] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(AmazonRecentComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/amazon-recent/amazon-recent.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | import {ApiService} from '../../../../api.service'; 3 | import {AuthenticationService} from '../../../../auth/authentication.service'; 4 | import {MessageService} from '../../../../message.service'; 5 | import {HttpParams} from '@angular/common/http'; 6 | import {AmazonPlayLog} from '../model/AmazonPlayLog'; 7 | import {NgxIndexedDBService} from 'ngx-indexed-db'; 8 | import {ChuniMusic, Difficulty} from '../model/ChuniMusic'; 9 | import {environment} from '../../../../../environments/environment'; 10 | import {map, tap} from 'rxjs/operators'; 11 | import {Observable} from 'rxjs'; 12 | 13 | @Component({ 14 | selector: 'app-amazon-recent', 15 | templateUrl: './amazon-recent.component.html', 16 | styleUrls: ['./amazon-recent.component.css'] 17 | }) 18 | export class AmazonRecentComponent implements OnInit { 19 | 20 | host = environment.assetsHost; 21 | 22 | aimeId: string; 23 | 24 | recent: Observable; 25 | difficulty = Difficulty; 26 | 27 | currentPage = 1; 28 | totalElements = 0; 29 | 30 | constructor( 31 | private api: ApiService, 32 | private auth: AuthenticationService, 33 | private messageService: MessageService, 34 | private dbService: NgxIndexedDBService 35 | ) { 36 | } 37 | 38 | ngOnInit() { 39 | this.aimeId = String(this.auth.currentUserValue.extId); 40 | this.load(this.currentPage); 41 | } 42 | 43 | load(page: number) { 44 | const param = new HttpParams().set('aimeId', this.aimeId).set('page', String(page - 1)); 45 | this.recent = this.api.get('api/game/chuni/amazon/recent', param).pipe( 46 | tap( 47 | data => { 48 | this.totalElements = data.totalElements; 49 | this.currentPage = page; 50 | } 51 | ), 52 | map( 53 | data => { 54 | data.content.forEach(x => { 55 | this.dbService.getByID('chuniMusic', x.musicId).then( 56 | m => x.songInfo = m 57 | ); 58 | }); 59 | return data.content; 60 | }, 61 | error => this.messageService.notice(error) 62 | ) 63 | ); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/amazon-setting/amazon-name-setting/amazon-name-setting.dialog.ts: -------------------------------------------------------------------------------- 1 | import {Component, Inject} from '@angular/core'; 2 | import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog'; 3 | 4 | @Component({ 5 | selector: 'amazon-name-setting-dialog', 6 | templateUrl: 'amazon-name-setting.html', 7 | }) 8 | export class AmazonNameSettingDialog { 9 | 10 | constructor( 11 | public dialogRef: MatDialogRef, 12 | @Inject(MAT_DIALOG_DATA) public data: AmazonNameSettingData) { 13 | } 14 | 15 | onNoClick(): void { 16 | this.dialogRef.close(); 17 | } 18 | 19 | } 20 | 21 | export interface AmazonNameSettingData { 22 | userName: string; 23 | } 24 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/amazon-setting/amazon-name-setting/amazon-name-setting.html: -------------------------------------------------------------------------------- 1 |

Change User Name

2 |
3 | 4 | 5 | 6 |
7 |
8 | 9 | 10 |
11 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/amazon-setting/amazon-setting.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samnyan/aqua-viewer/a718036ab6baa92d9aa469a9997b3c73e6d9bb1d/src/app/sega/chunithm/amazon/amazon-setting/amazon-setting.component.css -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/amazon-setting/amazon-setting.component.html: -------------------------------------------------------------------------------- 1 | 2 | CHUNITHM Settings 3 | 4 | 5 | 6 | Username 7 | 8 |
{{profile.userName}}
9 |
10 | 11 |
12 |
13 |
14 | 15 | 16 | Privacy 17 | 18 |
Hide Rating Info:
19 |
20 | 21 |
22 |
23 |
24 | 25 | 26 | Export data 27 | 28 |
29 | Download 30 |
31 |
32 |
33 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/amazon-setting/amazon-setting.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { AmazonSettingComponent } from './amazon-setting.component'; 4 | 5 | describe('AmazonSettingComponent', () => { 6 | let component: AmazonSettingComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ AmazonSettingComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(AmazonSettingComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/amazon-setting/amazon-setting.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | import {ApiService} from '../../../../api.service'; 3 | import {AuthenticationService} from '../../../../auth/authentication.service'; 4 | import {MessageService} from '../../../../message.service'; 5 | import {MatDialog} from '@angular/material/dialog'; 6 | import {AmazonProfile} from '../model/AmazonProfile'; 7 | import {HttpParams} from '@angular/common/http'; 8 | import {AmazonNameSettingDialog} from './amazon-name-setting/amazon-name-setting.dialog'; 9 | 10 | @Component({ 11 | selector: 'app-amazon-setting', 12 | templateUrl: './amazon-setting.component.html', 13 | styleUrls: ['./amazon-setting.component.css'] 14 | }) 15 | export class AmazonSettingComponent implements OnInit { 16 | 17 | profile: AmazonProfile; 18 | aimeId: string; 19 | apiServer: string; 20 | 21 | constructor( 22 | private api: ApiService, 23 | private auth: AuthenticationService, 24 | private messageService: MessageService, 25 | public dialog: MatDialog 26 | ) { } 27 | 28 | ngOnInit() { 29 | this.aimeId = String(this.auth.currentUserValue.extId); 30 | this.apiServer = this.auth.currentUserValue.apiServer; 31 | const param = new HttpParams().set('aimeId', this.aimeId); 32 | this.api.get('api/game/chuni/amazon/profile', param).subscribe( 33 | data => { 34 | this.profile = data; 35 | }, 36 | error => this.messageService.notice(error) 37 | ); 38 | } 39 | 40 | userName() { 41 | const dialogRef = this.dialog.open(AmazonNameSettingDialog, { 42 | width: '250px', 43 | data: {userName: this.profile.userName} 44 | }); 45 | 46 | dialogRef.afterClosed().subscribe(userName => { 47 | if (userName) { 48 | this.api.put('api/game/chuni/amazon/profile/userName', {aimeId: this.aimeId, userName}).subscribe( 49 | x => { 50 | this.profile = x; 51 | this.messageService.notice('OK'); 52 | }, error => this.messageService.notice(error) 53 | ); 54 | } 55 | }); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/amazon-song-detail/amazon-song-detail.component.css: -------------------------------------------------------------------------------- 1 | .song-info { 2 | display: flex; 3 | } 4 | 5 | .song-info img { 6 | width: 128px; 7 | height: 128px; 8 | } 9 | 10 | .text-content { 11 | margin-left: 12px; 12 | } 13 | 14 | .text-content .title { 15 | font-size: 1.5em; 16 | } 17 | 18 | .level-title { 19 | display: flex; 20 | } 21 | 22 | .level-title .level { 23 | margin-left: auto; 24 | font-size: 0.75em; 25 | } 26 | 27 | .result-content { 28 | display: flex; 29 | } 30 | 31 | .result-content .left { 32 | min-width: 30%; 33 | text-align: center; 34 | margin: auto; 35 | } 36 | 37 | .score-rank-icon { 38 | font-size: 1.5rem; 39 | } 40 | 41 | .score-value { 42 | font-size: 1.4rem; 43 | } 44 | 45 | mat-card-actions { 46 | display: flex; 47 | padding-bottom: 0; 48 | } 49 | 50 | mat-card-actions button { 51 | margin-left: auto; 52 | } 53 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/amazon-song-detail/amazon-song-detail.component.spec.ts: -------------------------------------------------------------------------------- 1 | import {async, ComponentFixture, TestBed} from '@angular/core/testing'; 2 | 3 | import {AmazonSongDetailComponent} from './amazon-song-detail.component'; 4 | 5 | describe('AmazonSongDetailComponent', () => { 6 | let component: AmazonSongDetailComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [AmazonSongDetailComponent] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(AmazonSongDetailComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/amazon-song-detail/amazon-song-detail.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | import {ActivatedRoute, Router} from '@angular/router'; 3 | import {ApiService} from '../../../../api.service'; 4 | import {AuthenticationService} from '../../../../auth/authentication.service'; 5 | import {ChuniMusic, ChuniMusicLevelInfo, Difficulty} from '../model/ChuniMusic'; 6 | import {NgxIndexedDBService} from 'ngx-indexed-db'; 7 | import {environment} from '../../../../../environments/environment'; 8 | import {HttpParams} from '@angular/common/http'; 9 | import {MessageService} from '../../../../message.service'; 10 | import {AmazonRecord} from '../model/AmazonRecord'; 11 | 12 | @Component({ 13 | selector: 'app-amazon-song-detail', 14 | templateUrl: './amazon-song-detail.component.html', 15 | styleUrls: ['./amazon-song-detail.component.css'] 16 | }) 17 | export class AmazonSongDetailComponent implements OnInit { 18 | 19 | host = environment.assetsHost; 20 | 21 | id: number; 22 | music: ChuniMusic; 23 | levels: ChuniMusicLevelInfo[] = []; 24 | difficulty = Difficulty; 25 | records: AmazonRecord[] = [null, null, null, null, null]; 26 | 27 | constructor( 28 | private route: ActivatedRoute, 29 | private router: Router, 30 | private api: ApiService, 31 | private auth: AuthenticationService, 32 | private messageService: MessageService, 33 | private dbService: NgxIndexedDBService 34 | ) { 35 | } 36 | 37 | ngOnInit() { 38 | this.id = Number(this.route.snapshot.paramMap.get('id')); 39 | const aimeId = String(this.auth.currentUserValue.extId); 40 | const param = new HttpParams().set('aimeId', String(aimeId)); 41 | this.dbService.getByID('chuniMusic', this.id).then(x => { 42 | if (x) { 43 | this.music = x; 44 | for (const key of Object.keys(this.music.levels)) { 45 | if (this.music.levels[key].enable) { 46 | this.levels.push(this.music.levels[key]); 47 | } 48 | } 49 | } 50 | 51 | }); 52 | this.api.get('api/game/chuni/amazon/song/' + this.id, param).subscribe( 53 | data => { 54 | console.log(data); 55 | data.forEach(x => { 56 | this.records[x.level] = x; 57 | }); 58 | }, 59 | error => this.messageService.notice(error) 60 | ); 61 | 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/amazon-song-playlog/amazon-song-playlog.component.css: -------------------------------------------------------------------------------- 1 | .record mat-card-title { 2 | font-size: 1.2em; 3 | text-align: right; 4 | } 5 | 6 | .song-header { 7 | display: flex; 8 | } 9 | 10 | .song-header img { 11 | width: 42px; 12 | height: 42px; 13 | } 14 | 15 | .song-header .level { 16 | margin-left: auto; 17 | font-size: 1.2em; 18 | } 19 | 20 | .song-info { 21 | margin-left: 4px; 22 | } 23 | 24 | .song-info .title { 25 | font-size: 1.2em; 26 | } 27 | 28 | .song-info .info { 29 | color: #cfcfcf; 30 | } 31 | 32 | .result-content { 33 | display: flex; 34 | } 35 | 36 | .result-content .left { 37 | min-width: 30%; 38 | text-align: center; 39 | margin: auto; 40 | } 41 | 42 | .achievement-value { 43 | font-size: 1.5rem; 44 | } 45 | 46 | .score-value { 47 | font-size: 1.4rem; 48 | } 49 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/amazon-song-playlog/amazon-song-playlog.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Play History 4 | 5 | 6 | 7 |
8 | 9 | {{item.userPlayDate}} 10 | 11 |
12 | 13 |
14 | {{songInfo != null ? songInfo.name : 'musicId:' + id}}
15 | {{songInfo != null ? songInfo.artistName : ''}} 17 |
18 |
19 | {{difficulty[item.level]}} 20 |
21 |
22 | 23 |
24 |
25 | Rank:
26 | {{item.rank|toRank}} 27 |
28 |
Score:
29 | {{item.score}} 30 |
31 |
{{item.isNewRecord ? 'NEW RECORD' : ''}}
32 |
33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 |
JUSTICE C.{{item.judgeCritical}}TAP{{item.rateTap / 100}}%
JUSTICE{{item.judgeJustice}}HOLD{{item.rateHold / 100}}%
ATTACK{{item.judgeAttack}}SLIDE{{item.rateSlide / 100}}%
MISS{{item.judgeGuilty}}AIR{{item.rateAir / 100}}%
Combo{{item.maxCombo}}FLICK{{item.rateFlick / 100}}%
65 |
66 |
67 |
68 | 69 |
70 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/amazon-song-playlog/amazon-song-playlog.component.spec.ts: -------------------------------------------------------------------------------- 1 | import {async, ComponentFixture, TestBed} from '@angular/core/testing'; 2 | 3 | import {AmazonSongPlaylogComponent} from './amazon-song-playlog.component'; 4 | 5 | describe('AmazonSongPlaylogComponent', () => { 6 | let component: AmazonSongPlaylogComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [AmazonSongPlaylogComponent] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(AmazonSongPlaylogComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/amazon-song-playlog/amazon-song-playlog.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | import {environment} from '../../../../../environments/environment'; 3 | import {AmazonPlayLog} from '../model/AmazonPlayLog'; 4 | import {HttpParams} from '@angular/common/http'; 5 | import {ChuniMusic, Difficulty} from '../model/ChuniMusic'; 6 | import {ApiService} from '../../../../api.service'; 7 | import {AuthenticationService} from '../../../../auth/authentication.service'; 8 | import {MessageService} from '../../../../message.service'; 9 | import {NgxIndexedDBService} from 'ngx-indexed-db'; 10 | import {ActivatedRoute} from '@angular/router'; 11 | 12 | @Component({ 13 | selector: 'app-amazon-song-playlog', 14 | templateUrl: './amazon-song-playlog.component.html', 15 | styleUrls: ['./amazon-song-playlog.component.css'] 16 | }) 17 | export class AmazonSongPlaylogComponent implements OnInit { 18 | 19 | host = environment.assetsHost; 20 | 21 | id: number; 22 | level: number; 23 | records: AmazonPlayLog[] = []; 24 | songInfo: ChuniMusic; 25 | difficulty = Difficulty; 26 | 27 | constructor( 28 | private api: ApiService, 29 | private auth: AuthenticationService, 30 | private route: ActivatedRoute, 31 | private messageService: MessageService, 32 | private dbService: NgxIndexedDBService 33 | ) { 34 | } 35 | 36 | ngOnInit() { 37 | this.id = Number(this.route.snapshot.paramMap.get('id')); 38 | this.level = Number(this.route.snapshot.paramMap.get('level')); 39 | const aimeId = String(this.auth.currentUserValue.extId); 40 | const param = new HttpParams().set('aimeId', aimeId); 41 | this.api.get('api/game/chuni/amazon/song/' + this.id + '/' + this.level, param).subscribe( 42 | data => { 43 | data.forEach(x => { 44 | this.records.push(x); 45 | }); 46 | }, 47 | error => this.messageService.notice(error) 48 | ); 49 | this.dbService.getByID('chuniMusic', this.id).then( 50 | m => this.songInfo = m 51 | ); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/amazon-songlist/amazon-songlist.component.css: -------------------------------------------------------------------------------- 1 | table { 2 | width: 100%; 3 | } 4 | 5 | .mat-form-field { 6 | font-size: 14px; 7 | width: 100%; 8 | } 9 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/amazon-songlist/amazon-songlist.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
Id. {{element.musicId}} Name {{element.name}} Artist {{element.artistName}}
21 | 22 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/amazon-songlist/amazon-songlist.component.spec.ts: -------------------------------------------------------------------------------- 1 | import {async, ComponentFixture, TestBed} from '@angular/core/testing'; 2 | 3 | import {AmazonSonglistComponent} from './amazon-songlist.component'; 4 | 5 | describe('AmazonSonglistComponent', () => { 6 | let component: AmazonSonglistComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [AmazonSonglistComponent] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(AmazonSonglistComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/amazon-songlist/amazon-songlist.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit, ViewChild} from '@angular/core'; 2 | import {MatPaginator} from '@angular/material/paginator'; 3 | import {MatTableDataSource} from '@angular/material/table'; 4 | import {ChuniMusic} from '../model/ChuniMusic'; 5 | import {NgxIndexedDBService} from 'ngx-indexed-db'; 6 | 7 | @Component({ 8 | selector: 'app-amazon-songlist', 9 | templateUrl: './amazon-songlist.component.html', 10 | styleUrls: ['./amazon-songlist.component.css'] 11 | }) 12 | export class AmazonSonglistComponent implements OnInit { 13 | 14 | dataSource = new MatTableDataSource(); 15 | songList: ChuniMusic[] = []; 16 | displayedColumns: string[] = ['musicId', 'name', 'artistName']; 17 | 18 | @ViewChild(MatPaginator, {static: true}) paginator: MatPaginator; 19 | 20 | constructor(private dbService: NgxIndexedDBService) { 21 | } 22 | 23 | ngOnInit() { 24 | this.dbService.getAll('chuniMusic').then( 25 | x => { 26 | this.songList = x; 27 | this.dataSource.data = this.songList; 28 | } 29 | ); 30 | this.dataSource.paginator = this.paginator; 31 | } 32 | 33 | applyFilter(filterValue: string) { 34 | this.dataSource.filter = filterValue.trim().toLowerCase(); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/amazon.routing.ts: -------------------------------------------------------------------------------- 1 | import {RouterModule, Routes} from '@angular/router'; 2 | import {AmazonProfileComponent} from './amazon-profile/amazon-profile.component'; 3 | import {AmazonRatingComponent} from './amazon-rating/amazon-rating.component'; 4 | import {AmazonRecentComponent} from './amazon-recent/amazon-recent.component'; 5 | import {AmazonSettingComponent} from './amazon-setting/amazon-setting.component'; 6 | import {AmazonSonglistComponent} from './amazon-songlist/amazon-songlist.component'; 7 | import {AmazonCharacterComponent} from './amazon-character/amazon-character.component'; 8 | import {AmazonSongDetailComponent} from './amazon-song-detail/amazon-song-detail.component'; 9 | import {AmazonSongPlaylogComponent} from './amazon-song-playlog/amazon-song-playlog.component'; 10 | 11 | const routes: Routes = [ 12 | {path: 'profile', component: AmazonProfileComponent}, 13 | {path: 'rating', component: AmazonRatingComponent}, 14 | {path: 'recent', component: AmazonRecentComponent}, 15 | {path: 'song', component: AmazonSonglistComponent}, 16 | {path: 'song/:id', component: AmazonSongDetailComponent}, 17 | {path: 'song/:id/:level', component: AmazonSongPlaylogComponent}, 18 | {path: 'character', component: AmazonCharacterComponent}, 19 | {path: 'setting', component: AmazonSettingComponent}, 20 | ]; 21 | 22 | export const AmazonRoutes = RouterModule.forChild(routes); 23 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/chuni-music-db.service.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from '@angular/core'; 2 | import {ChuniMusic} from './model/ChuniMusic'; 3 | import {ApiService} from '../../../api.service'; 4 | import {Subject} from 'rxjs'; 5 | 6 | @Injectable({ 7 | providedIn: 'root' 8 | }) 9 | export class ChuniMusicDbService { 10 | 11 | private dbSubject = new Subject>(); 12 | dbState = this.dbSubject.asObservable(); 13 | 14 | musicDb: Map; 15 | 16 | constructor(private api: ApiService) { 17 | let db = localStorage.getItem('chuniMusicDb'); 18 | if (db == null) { 19 | this.api.get('api/game/chuni/amazon/music').subscribe( 20 | data => { 21 | db = data; 22 | localStorage.setItem('chuniMusicDb', JSON.stringify(db)); 23 | this.musicDb = this.parse(JSON.parse(db)); 24 | } 25 | ); 26 | } else { 27 | this.musicDb = this.parse(JSON.parse(db)); 28 | } 29 | } 30 | 31 | get(id: number): ChuniMusic { 32 | return this.musicDb.get(id); 33 | } 34 | 35 | getMusicDb(): Map { 36 | return this.musicDb; 37 | } 38 | 39 | private parse(db: ChuniMusic[]): Map { 40 | const result: Map = new Map(); 41 | db.forEach(x => { 42 | result.set(x.musicId, x); 43 | }); 44 | return result; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/model/AmazonCharacter.ts: -------------------------------------------------------------------------------- 1 | import {ChuniCharacter} from './ChuniCharacter'; 2 | import {ChuniSkill} from './ChuniSkill'; 3 | 4 | export interface AmazonCharacter { 5 | characterId: number; 6 | playCount: number; 7 | level: number; 8 | skillId: number; 9 | friendshipExp: number; 10 | isValid: boolean; 11 | isNewMark: boolean; 12 | param1: string; 13 | param2: string; 14 | characterInfo: ChuniCharacter; 15 | skillInfo: ChuniSkill; 16 | } 17 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/model/AmazonPlayLog.ts: -------------------------------------------------------------------------------- 1 | import {ChuniMusic} from './ChuniMusic'; 2 | 3 | export interface AmazonPlayLog { 4 | playDate: Date; 5 | userPlayDate: Date; 6 | musicId: number; 7 | songInfo?: ChuniMusic; 8 | level: number; 9 | customId: number; 10 | playedCustom1: number; 11 | playedCustom2: number; 12 | playedCustom3: number; 13 | track: number; 14 | score: number; 15 | rank: number; 16 | maxCombo: number; 17 | maxChain: number; 18 | rateTap: number; 19 | rateHold: number; 20 | rateSlide: number; 21 | rateAir: number; 22 | rateFlick: number; 23 | judgeGuilty: number; 24 | judgeAttack: number; 25 | judgeJustice: number; 26 | judgeCritical: number; 27 | playerRating: number; 28 | fullChainKind: number; 29 | characterId: number; 30 | skillId: number; 31 | playKind: number; 32 | skillLevel: number; 33 | skillEffect: number; 34 | isNewRecord: boolean; 35 | isFullCombo: boolean; 36 | isAllJustice: boolean; 37 | isClear: boolean; 38 | } 39 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/model/AmazonProfile.ts: -------------------------------------------------------------------------------- 1 | export interface AmazonProfile { 2 | userName: string; 3 | level: number; 4 | exp: number; 5 | point: number; 6 | totalPoint: bigint; 7 | playCount: number; 8 | multiPlayCount: number; 9 | multiWinCount: number; 10 | requestResCount: number; 11 | acceptResCount: number; 12 | successResCount: number; 13 | playerRating: number; 14 | highestRating: number; 15 | nameplateId: number; 16 | frameId: number; 17 | characterId: number; 18 | trophyId: number; 19 | playedTutorialBit: number; 20 | firstTutorialCancelNum: number; 21 | masterTutorialCancelNum: number; 22 | totalRepertoireCount: number; 23 | totalMapNum: number; 24 | totalHiScore: bigint; 25 | totalBasicHighScore: bigint; 26 | totalAdvancedHighScore: bigint; 27 | totalExpertHighScore: bigint; 28 | totalMasterHighScore: bigint; 29 | friendCount: number; 30 | firstGameId: string; 31 | firstRomVersion: string; 32 | firstDataVersion: string; 33 | firstPlayDate: Date; 34 | lastPlayDate: Date; 35 | courseClass: number; 36 | } 37 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/model/AmazonRecord.ts: -------------------------------------------------------------------------------- 1 | export interface AmazonRecord { 2 | musicId: number; 3 | level: number; 4 | playCount: number; 5 | scoreMax: number; 6 | resRequestCount: number; 7 | resAcceptCount: number; 8 | resSuccessCount: number; 9 | missCount: number; 10 | maxComboCount: number; 11 | isFullCombo: boolean; 12 | isAllJustice: boolean; 13 | isSuccess: boolean; 14 | fullChain: number; 15 | maxChain: number; 16 | scoreRank: number; 17 | isLock: boolean; 18 | } 19 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/model/ChuniCharacter.ts: -------------------------------------------------------------------------------- 1 | export interface ChuniCharacter { 2 | id: number; 3 | name: string; 4 | releaseTag: string; 5 | worksName: string; 6 | illustratorName: string; 7 | firstSkillId: number; 8 | skills: string; 9 | addImages: string; 10 | } 11 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/model/ChuniMusic.ts: -------------------------------------------------------------------------------- 1 | export interface ChuniMusic { 2 | musicId: number; 3 | name: string; 4 | sotrName: string; 5 | copyright: string; 6 | artistName: string; 7 | genre: string; 8 | releaseVersion: string; 9 | levels: ChuniMusicLevels; 10 | } 11 | 12 | export interface ChuniMusicLevels { 13 | 0: ChuniMusicLevelInfo; 14 | 1: ChuniMusicLevelInfo; 15 | 2: ChuniMusicLevelInfo; 16 | 3: ChuniMusicLevelInfo; 17 | 4: ChuniMusicLevelInfo; 18 | } 19 | 20 | export interface ChuniMusicLevelInfo { 21 | enable: boolean; 22 | level: number; 23 | levelDecimal: number; 24 | diff: number; 25 | } 26 | 27 | export enum Difficulty { 28 | BASIC = 0, 29 | ADVANCED = 1, 30 | EXPERT = 2, 31 | MASTER = 3, 32 | WORLD_END = 4, 33 | } 34 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/model/ChuniSkill.ts: -------------------------------------------------------------------------------- 1 | export interface ChuniSkill { 2 | id: number; 3 | name: string; 4 | category: string; 5 | } 6 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/util/cource-id-to-class.pipe.spec.ts: -------------------------------------------------------------------------------- 1 | import {CourceIdToClassPipe} from './cource-id-to-class.pipe'; 2 | 3 | describe('CourceIdToClassPipe', () => { 4 | it('create an instance', () => { 5 | const pipe = new CourceIdToClassPipe(); 6 | expect(pipe).toBeTruthy(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/util/cource-id-to-class.pipe.ts: -------------------------------------------------------------------------------- 1 | import {Pipe, PipeTransform} from '@angular/core'; 2 | 3 | @Pipe({ 4 | name: 'courceIdToClass' 5 | }) 6 | export class CourceIdToClassPipe implements PipeTransform { 7 | 8 | transform(v: number): number { 9 | switch (true) { 10 | case (v === 10): 11 | return 1; 12 | case (v === 11): 13 | return 2; 14 | case (v === 12): 15 | return 3; 16 | case (v === 13): 17 | return 4; 18 | case (v === 14): 19 | return 5; 20 | case (v === 20): 21 | return 6; // infinity 22 | case (v === 21): 23 | return 7; // class unknown 24 | } 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/util/rating-class.pipe.ts: -------------------------------------------------------------------------------- 1 | import {Pipe, PipeTransform} from '@angular/core'; 2 | 3 | @Pipe({ 4 | name: 'ratingClass' 5 | }) 6 | export class RatingClass implements PipeTransform { 7 | 8 | transform(s: number, args?: any): string { 9 | switch (true) { 10 | case (s < 2.0): 11 | return 'lv8'; 12 | case (s < 4.0): 13 | return 'lv6'; 14 | case (s < 7.0): 15 | return 'lv2'; 16 | case (s < 10.0): 17 | return 'lv12'; 18 | case (s < 12.0): 19 | return 'lv10'; 20 | case (s < 13.0): 21 | return 'lv14'; 22 | case (s < 14.0): 23 | return 'lv15'; 24 | case (s < 14.5): 25 | return 'lv16'; 26 | case (s < 15.0): 27 | return 'lv0'; 28 | case (s >= 15.0): 29 | return 'lv17'; 30 | } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/util/to-rank.pipe.spec.ts: -------------------------------------------------------------------------------- 1 | import {ToRankPipe} from './to-rank.pipe'; 2 | 3 | describe('ToRankPipe', () => { 4 | it('create an instance', () => { 5 | const pipe = new ToRankPipe(); 6 | expect(pipe).toBeTruthy(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/util/to-rank.pipe.ts: -------------------------------------------------------------------------------- 1 | import {Pipe, PipeTransform} from '@angular/core'; 2 | 3 | @Pipe({ 4 | name: 'toRank' 5 | }) 6 | export class ToRankPipe implements PipeTransform { 7 | 8 | transform(value: number): string { 9 | if (value === 0) { 10 | return 'D'; 11 | } 12 | if (value === 1) { 13 | return 'C'; 14 | } 15 | if (value === 2) { 16 | return 'B'; 17 | } 18 | if (value === 3) { 19 | return 'BB'; 20 | } 21 | if (value === 4) { 22 | return 'BBB'; 23 | } 24 | if (value === 5) { 25 | return 'A'; 26 | } 27 | if (value === 6) { 28 | return 'AA'; 29 | } 30 | if (value === 7) { 31 | return 'AAA'; 32 | } 33 | if (value === 8) { 34 | return 'S'; 35 | } 36 | if (value === 9) { 37 | return 'SS'; 38 | } 39 | if (value === 10) { 40 | return 'SSS'; 41 | } 42 | if (value > 10) { 43 | return 'SSS'; 44 | } 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/util/to-rating.pipe.spec.ts: -------------------------------------------------------------------------------- 1 | import {ToRatingPipe} from './to-rating.pipe'; 2 | 3 | describe('ToRatingPipe', () => { 4 | it('create an instance', () => { 5 | const pipe = new ToRatingPipe(); 6 | expect(pipe).toBeTruthy(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /src/app/sega/chunithm/amazon/util/to-rating.pipe.ts: -------------------------------------------------------------------------------- 1 | import {Pipe, PipeTransform} from '@angular/core'; 2 | 3 | @Pipe({ 4 | name: 'toRating' 5 | }) 6 | export class ToRatingPipe implements PipeTransform { 7 | 8 | transform(value: number): number { 9 | return Math.floor(value) / 100; 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-customize/diva-customize.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samnyan/aqua-viewer/a718036ab6baa92d9aa469a9997b3c73e6d9bb1d/src/app/sega/diva/diva-customize/diva-customize.component.css -------------------------------------------------------------------------------- /src/app/sega/diva/diva-customize/diva-customize.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | Module ID: {{item.id}}

5 | Name: {{item.name}}
6 | Price: {{item.price}} VP 7 |
8 |
9 |
10 | 20 | 21 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-customize/diva-customize.component.spec.ts: -------------------------------------------------------------------------------- 1 | import {async, ComponentFixture, TestBed} from '@angular/core/testing'; 2 | 3 | import {DivaCustomizeComponent} from './diva-customize.component'; 4 | 5 | describe('DivaCustomizeComponent', () => { 6 | let component: DivaCustomizeComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [DivaCustomizeComponent] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(DivaCustomizeComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-customize/diva-customize.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | import {DivaCustomize} from '../model/DivaCustomize'; 3 | import {NgxIndexedDBService} from 'ngx-indexed-db'; 4 | 5 | @Component({ 6 | selector: 'app-diva-customize', 7 | templateUrl: './diva-customize.component.html', 8 | styleUrls: ['./diva-customize.component.css'] 9 | }) 10 | export class DivaCustomizeComponent implements OnInit { 11 | 12 | p = 0; 13 | customizes: DivaCustomize[] = []; 14 | 15 | constructor(private dbService: NgxIndexedDBService) { 16 | } 17 | 18 | ngOnInit() { 19 | this.dbService.getAll('divaCustomize').then( 20 | x => x.forEach(y => this.customizes.push(y)) 21 | ); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-management/diva-contest/diva-contest-edit/diva-contest-edit.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samnyan/aqua-viewer/a718036ab6baa92d9aa469a9997b3c73e6d9bb1d/src/app/sega/diva/diva-management/diva-contest/diva-contest-edit/diva-contest-edit.component.css -------------------------------------------------------------------------------- /src/app/sega/diva/diva-management/diva-contest/diva-contest-edit/diva-contest-edit.component.spec.ts: -------------------------------------------------------------------------------- 1 | import {async, ComponentFixture, TestBed} from '@angular/core/testing'; 2 | 3 | import {DivaContestEditComponent} from './diva-contest-edit.component'; 4 | 5 | describe('DivaContestEditComponent', () => { 6 | let component: DivaContestEditComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [DivaContestEditComponent] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(DivaContestEditComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-management/diva-contest/diva-contest.component.css: -------------------------------------------------------------------------------- 1 | mat-card-title { 2 | font-size: 1.2em; 3 | display: flex; 4 | } 5 | 6 | mat-card-title button { 7 | margin-left: auto; 8 | } 9 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-management/diva-contest/diva-contest.component.spec.ts: -------------------------------------------------------------------------------- 1 | import {async, ComponentFixture, TestBed} from '@angular/core/testing'; 2 | 3 | import {DivaContestComponent} from './diva-contest.component'; 4 | 5 | describe('DivaContestComponent', () => { 6 | let component: DivaContestComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [DivaContestComponent] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(DivaContestComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-management/diva-contest/diva-contest.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | import {ApiService} from '../../../../api.service'; 3 | import {MessageService} from '../../../../message.service'; 4 | import {Router} from '@angular/router'; 5 | import {DivaContestService} from './diva-contest.service'; 6 | import {Contest, ContestLeague, ContestNormaType, ContestStageLimit} from '../../model/mannagement/contest'; 7 | 8 | @Component({ 9 | selector: 'app-diva-contest', 10 | templateUrl: './diva-contest.component.html', 11 | styleUrls: ['./diva-contest.component.css'] 12 | }) 13 | export class DivaContestComponent implements OnInit { 14 | 15 | contests: Contest[]; 16 | contestLeague = ContestLeague; 17 | contestStageLimit = ContestStageLimit; 18 | contestNormaType = ContestNormaType; 19 | 20 | constructor( 21 | private api: ApiService, 22 | private messageService: MessageService, 23 | private contestService: DivaContestService, 24 | private router: Router 25 | ) { 26 | } 27 | 28 | ngOnInit() { 29 | this.load(); 30 | } 31 | 32 | load() { 33 | this.api.get('api/manage/diva/contest').subscribe( 34 | data => this.contests = data, 35 | error => this.messageService.notice(error) 36 | ); 37 | } 38 | 39 | delete(id) { 40 | this.api.delete('api/manage/diva/contest/' + id).subscribe( 41 | () => { 42 | this.messageService.notice('OK'); 43 | this.load(); 44 | }, 45 | error => { 46 | this.messageService.notice(error); 47 | this.load(); 48 | } 49 | ); 50 | } 51 | 52 | edit(contest) { 53 | this.contestService.contest = contest; 54 | this.router.navigateByUrl('/diva/management/contest/edit'); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-management/diva-contest/diva-contest.service.spec.ts: -------------------------------------------------------------------------------- 1 | import {TestBed} from '@angular/core/testing'; 2 | 3 | import {DivaContestService} from './diva-contest.service'; 4 | 5 | describe('DivaContestService', () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it('should be created', () => { 9 | const service: DivaContestService = TestBed.get(DivaContestService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-management/diva-contest/diva-contest.service.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from '@angular/core'; 2 | import {Contest, ContestLeague, ContestNormaType, ContestStageLimit} from '../../model/mannagement/contest'; 3 | 4 | @Injectable({ 5 | providedIn: 'root' 6 | }) 7 | export class DivaContestService { 8 | 9 | currentContest: Contest = undefined; 10 | 11 | constructor() { 12 | } 13 | 14 | get contest() { 15 | return this.currentContest === undefined ? { 16 | id: -1, 17 | enable: true, 18 | startTime: new Date(), 19 | endTime: new Date(), 20 | name: 'Untitled', 21 | description: 'description', 22 | league: ContestLeague.Intermediate, 23 | stars: 16, 24 | minComplexity: 10, 25 | maxComplexity: 20, 26 | stages: 4, 27 | stageLimit: ContestStageLimit.Limited, 28 | normaType: ContestNormaType.Percentage, 29 | bronzeBorders: 16000, 30 | sliverBorders: 28000, 31 | goldBorders: 32000, 32 | pvList: '', 33 | pvDiffList: '', 34 | bronzeContestReward: '', 35 | sliverContestReward: '', 36 | goldContestReward: '', 37 | contestEntryReward: '' 38 | } : this.currentContest; 39 | } 40 | 41 | set contest(f: Contest) { 42 | this.currentContest = f; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-management/diva-festa/diva-festa-edit/diva-festa-edit.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samnyan/aqua-viewer/a718036ab6baa92d9aa469a9997b3c73e6d9bb1d/src/app/sega/diva/diva-management/diva-festa/diva-festa-edit/diva-festa-edit.component.css -------------------------------------------------------------------------------- /src/app/sega/diva/diva-management/diva-festa/diva-festa-edit/diva-festa-edit.component.spec.ts: -------------------------------------------------------------------------------- 1 | import {async, ComponentFixture, TestBed} from '@angular/core/testing'; 2 | 3 | import {DivaFestaEditComponent} from './diva-festa-edit.component'; 4 | 5 | describe('DivaFestaEditComponent', () => { 6 | let component: DivaFestaEditComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [DivaFestaEditComponent] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(DivaFestaEditComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-management/diva-festa/diva-festa-edit/diva-festa-edit.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | import {ApiService} from '../../../../../api.service'; 3 | import {FormBuilder, FormGroup, Validators} from '@angular/forms'; 4 | import {DivaFestaService} from '../diva-festa.service'; 5 | import {Festa} from '../../../model/mannagement/Festa'; 6 | import {Router} from '@angular/router'; 7 | import {MessageService} from '../../../../../message.service'; 8 | 9 | @Component({ 10 | selector: 'app-diva-festa-edit', 11 | templateUrl: './diva-festa-edit.component.html', 12 | styleUrls: ['./diva-festa-edit.component.css'] 13 | }) 14 | export class DivaFestaEditComponent implements OnInit { 15 | 16 | festa: Festa; 17 | festaForm: FormGroup; 18 | 19 | constructor( 20 | private api: ApiService, 21 | private messageService: MessageService, 22 | private fb: FormBuilder, 23 | private festaService: DivaFestaService, 24 | private router: Router 25 | ) { 26 | } 27 | 28 | get f() { 29 | return this.festaForm.controls; 30 | } 31 | 32 | ngOnInit() { 33 | this.festa = this.festaService.festa; 34 | this.festaForm = this.fb.group({ 35 | id: [this.festa.id, Validators.required], 36 | name: [this.festa.name, Validators.required], 37 | enable: [this.festa.enable], 38 | kind: [String(this.festa.kind), Validators.required], 39 | difficulty: [String(this.festa.difficulty), Validators.required], 40 | pvList: [this.festa.pvList, Validators.required], 41 | attributes: [this.festa.attributes, Validators.required], 42 | addVP: [this.festa.addVP, Validators.required], 43 | vpMultiplier: [this.festa.vpMultiplier, Validators.required], 44 | start: [this.festa.start, Validators.required], 45 | end: [this.festa.end, Validators.required], 46 | createDate: [this.festa.createDate, Validators.required], 47 | }); 48 | } 49 | 50 | onSubmit() { 51 | this.api.put('api/manage/diva/festa', this.festaForm.value).subscribe( 52 | data => { 53 | console.log(data); 54 | this.router.navigateByUrl('/diva/management/festa'); 55 | }, 56 | error => this.messageService.notice(error) 57 | ); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-management/diva-festa/diva-festa.component.css: -------------------------------------------------------------------------------- 1 | mat-card-title { 2 | font-size: 1.2em; 3 | display: flex; 4 | } 5 | 6 | mat-card-title button { 7 | margin-left: auto; 8 | } 9 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-management/diva-festa/diva-festa.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
Festa List, Length: {{festas ? festas.length : 0}}
4 | 5 |
6 |
7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 |
ID{{festa.id}}
Name{{festa.name}}
FestaKind{{festaKind[festa.kind]}}
Difficulty{{difficulty[festa.difficulty]}}
PvList{{festa.pvList}}
Attributes{{festa.attributes}}
Add VP{{festa.addVP}}
VP Multiplier{{festa.vpMultiplier}}
Start{{festa.start}}
End{{festa.end}}
Create Date{{festa.createDate}}
56 |
57 | 58 | 59 | 60 | 61 |
62 |
63 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-management/diva-festa/diva-festa.component.spec.ts: -------------------------------------------------------------------------------- 1 | import {async, ComponentFixture, TestBed} from '@angular/core/testing'; 2 | 3 | import {DivaFestaComponent} from './diva-festa.component'; 4 | 5 | describe('DivaFestaComponent', () => { 6 | let component: DivaFestaComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [DivaFestaComponent] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(DivaFestaComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-management/diva-festa/diva-festa.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | import {ApiService} from '../../../../api.service'; 3 | import {MessageService} from '../../../../message.service'; 4 | import {Festa, FestaKind} from '../../model/mannagement/Festa'; 5 | import {DivaFestaService} from './diva-festa.service'; 6 | import {Router} from '@angular/router'; 7 | import {Difficulty} from '../../model/DivaPvRecord'; 8 | 9 | @Component({ 10 | selector: 'app-diva-festa', 11 | templateUrl: './diva-festa.component.html', 12 | styleUrls: ['./diva-festa.component.css'] 13 | }) 14 | export class DivaFestaComponent implements OnInit { 15 | 16 | festas: Festa[]; 17 | festaKind = FestaKind; 18 | difficulty = Difficulty; 19 | 20 | constructor( 21 | private api: ApiService, 22 | private messageService: MessageService, 23 | private festaService: DivaFestaService, 24 | private router: Router 25 | ) { 26 | } 27 | 28 | ngOnInit() { 29 | this.load(); 30 | } 31 | 32 | load() { 33 | this.api.get('api/manage/diva/festa').subscribe( 34 | data => this.festas = data, 35 | error => this.messageService.notice(error) 36 | ); 37 | } 38 | 39 | delete(id) { 40 | this.api.delete('api/manage/diva/festa/' + id).subscribe( 41 | () => { 42 | this.messageService.notice('OK'); 43 | this.load(); 44 | }, 45 | error => { 46 | this.messageService.notice(error); 47 | this.load(); 48 | } 49 | ); 50 | } 51 | 52 | edit(festa) { 53 | this.festaService.festa = festa; 54 | this.router.navigateByUrl('/diva/management/festa/edit'); 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-management/diva-festa/diva-festa.service.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from '@angular/core'; 2 | import {Festa} from '../../model/mannagement/Festa'; 3 | 4 | @Injectable({ 5 | providedIn: 'root' 6 | }) 7 | export class DivaFestaService { 8 | 9 | currentFesta: Festa = undefined; 10 | 11 | constructor() { 12 | } 13 | 14 | get festa() { 15 | return this.currentFesta === undefined ? { 16 | id: -1, 17 | enable: true, 18 | name: 'Untitled', 19 | kind: 0, 20 | difficulty: -1, 21 | pvList: 'ALL', 22 | attributes: '7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', 23 | addVP: 0, 24 | vpMultiplier: 1, 25 | start: new Date(), 26 | end: new Date(), 27 | createDate: new Date() 28 | } : this.currentFesta; 29 | } 30 | 31 | set festa(f: Festa) { 32 | this.currentFesta = f; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-management/diva-management/diva-management.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samnyan/aqua-viewer/a718036ab6baa92d9aa469a9997b3c73e6d9bb1d/src/app/sega/diva/diva-management/diva-management/diva-management.component.css -------------------------------------------------------------------------------- /src/app/sega/diva/diva-management/diva-management/diva-management.component.html: -------------------------------------------------------------------------------- 1 |

Management

2 | 3 | 4 | Festa 5 | 6 | 7 | Contest 8 | 9 | 10 | News / Warning 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-management/diva-management/diva-management.component.spec.ts: -------------------------------------------------------------------------------- 1 | import {async, ComponentFixture, TestBed} from '@angular/core/testing'; 2 | 3 | import {DivaManagementComponent} from './diva-management.component'; 4 | 5 | describe('DivaManagementComponent', () => { 6 | let component: DivaManagementComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [DivaManagementComponent] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(DivaManagementComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-management/diva-management/diva-management.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-diva-management', 5 | templateUrl: './diva-management.component.html', 6 | styleUrls: ['./diva-management.component.css'] 7 | }) 8 | export class DivaManagementComponent implements OnInit { 9 | 10 | constructor() { 11 | } 12 | 13 | ngOnInit() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-management/diva-news/diva-news.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samnyan/aqua-viewer/a718036ab6baa92d9aa469a9997b3c73e6d9bb1d/src/app/sega/diva/diva-management/diva-news/diva-news.component.css -------------------------------------------------------------------------------- /src/app/sega/diva/diva-management/diva-news/diva-news.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
News
4 |
5 | 6 |
7 | 8 | Content 9 | 10 | 11 | 12 |
13 |
14 |
15 | 16 | 17 | 18 |
Warning
19 |
20 | 21 |
22 | 23 | Content 24 | 25 | 26 | 27 |
28 |
29 |
30 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-management/diva-news/diva-news.component.spec.ts: -------------------------------------------------------------------------------- 1 | import {async, ComponentFixture, TestBed} from '@angular/core/testing'; 2 | 3 | import {DivaNewsComponent} from './diva-news.component'; 4 | 5 | describe('DivaNewsComponent', () => { 6 | let component: DivaNewsComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [DivaNewsComponent] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(DivaNewsComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-management/diva-news/diva-news.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | import {FormBuilder, FormGroup, Validators} from '@angular/forms'; 3 | import {ApiService} from '../../../../api.service'; 4 | import {MessageService} from '../../../../message.service'; 5 | 6 | @Component({ 7 | selector: 'app-diva-news', 8 | templateUrl: './diva-news.component.html', 9 | styleUrls: ['./diva-news.component.css'] 10 | }) 11 | export class DivaNewsComponent implements OnInit { 12 | 13 | newsForm: FormGroup; 14 | warningForm: FormGroup; 15 | 16 | constructor( 17 | private api: ApiService, 18 | private messageService: MessageService, 19 | private fb: FormBuilder, 20 | ) { 21 | } 22 | 23 | ngOnInit() { 24 | this.api.get('api/manage/diva/news').subscribe( 25 | data => this.createNews(data), 26 | error => this.messageService.notice(error) 27 | ); 28 | this.api.get('api/manage/diva/warning').subscribe( 29 | data => this.createWarning(data), 30 | error => this.messageService.notice(error) 31 | ); 32 | } 33 | 34 | createNews(data) { 35 | this.newsForm = this.fb.group({ 36 | propertyKey: [data.propertyKey, Validators.required], 37 | propertyValue: [data.propertyValue, Validators.required], 38 | }); 39 | } 40 | 41 | createWarning(data) { 42 | this.warningForm = this.fb.group({ 43 | propertyKey: [data.propertyKey, Validators.required], 44 | propertyValue: [data.propertyValue, Validators.required], 45 | }); 46 | } 47 | 48 | submitNews() { 49 | this.api.put('api/manage/diva/news', this.newsForm.value).subscribe( 50 | data => this.createNews(data), 51 | error => this.messageService.notice(error) 52 | ); 53 | } 54 | 55 | submitWarning() { 56 | this.api.put('api/manage/diva/warning', this.newsForm.value).subscribe( 57 | data => this.createWarning(data), 58 | error => this.messageService.notice(error) 59 | ); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-modules/diva-modules.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samnyan/aqua-viewer/a718036ab6baa92d9aa469a9997b3c73e6d9bb1d/src/app/sega/diva/diva-modules/diva-modules.component.css -------------------------------------------------------------------------------- /src/app/sega/diva/diva-modules/diva-modules.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | Module ID: {{item.id}}

5 | Name: {{item.name}}
6 | Price: {{item.price}} VP 7 |
8 |
9 |
10 | 20 | 21 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-modules/diva-modules.component.spec.ts: -------------------------------------------------------------------------------- 1 | import {async, ComponentFixture, TestBed} from '@angular/core/testing'; 2 | 3 | import {DivaModulesComponent} from './diva-modules.component'; 4 | 5 | describe('DivaModulesComponent', () => { 6 | let component: DivaModulesComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [DivaModulesComponent] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(DivaModulesComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-modules/diva-modules.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | import {DivaModule} from '../model/DivaModule'; 3 | import {NgxIndexedDBService} from 'ngx-indexed-db'; 4 | 5 | @Component({ 6 | selector: 'app-diva-modules', 7 | templateUrl: './diva-modules.component.html', 8 | styleUrls: ['./diva-modules.component.css'] 9 | }) 10 | export class DivaModulesComponent implements OnInit { 11 | 12 | p = 0; 13 | modules: DivaModule[] = []; 14 | 15 | constructor(private dbService: NgxIndexedDBService) { 16 | } 17 | 18 | ngOnInit() { 19 | this.dbService.getAll('divaModule').then( 20 | x => x.forEach(y => this.modules.push(y)) 21 | ); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-mylist.service.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from '@angular/core'; 2 | import {ApiService} from '../../api.service'; 3 | import {HttpParams} from '@angular/common/http'; 4 | import {AuthenticationService} from '../../auth/authentication.service'; 5 | import {DivaProfile} from './model/DivaProfile'; 6 | import {Observable} from 'rxjs'; 7 | 8 | @Injectable({ 9 | providedIn: 'root' 10 | }) 11 | export class DivaMylistService { 12 | 13 | profile: DivaProfile; 14 | 15 | constructor( 16 | private api: ApiService, 17 | private auth: AuthenticationService, 18 | ) { 19 | } 20 | 21 | getProfile() { 22 | const pdId = String(this.auth.currentUserValue.extId); 23 | const param = new HttpParams().set('pdId', pdId); 24 | return this.api.get('api/game/diva/playerInfo', param); 25 | } 26 | 27 | addMyList(listId: number, pvId: number): Observable { 28 | return new Observable((observer) => { 29 | this.getProfile().subscribe( 30 | data => { 31 | this.profile = data; 32 | observer.next(this.profile); 33 | observer.complete(); 34 | }, 35 | error => observer.error(new Error('Get profile fail')) 36 | ); 37 | }); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-profile/diva-profile.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samnyan/aqua-viewer/a718036ab6baa92d9aa469a9997b3c73e6d9bb1d/src/app/sega/diva/diva-profile/diva-profile.component.css -------------------------------------------------------------------------------- /src/app/sega/diva/diva-profile/diva-profile.component.html: -------------------------------------------------------------------------------- 1 | 2 | Player Profile 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
Project DIVA ID{{profile.pdId}}
Player Name{{profile.playerName}}
Player Level{{profile.level}}
Level Exp{{profile.levelExp}}%
Player Title{{profile.levelTitle}}
26 |
27 |
28 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-profile/diva-profile.component.spec.ts: -------------------------------------------------------------------------------- 1 | import {async, ComponentFixture, TestBed} from '@angular/core/testing'; 2 | 3 | import {DivaProfileComponent} from './diva-profile.component'; 4 | 5 | describe('DivaProfileComponent', () => { 6 | let component: DivaProfileComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [DivaProfileComponent] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(DivaProfileComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-profile/diva-profile.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | import {ApiService} from '../../../api.service'; 3 | import {DivaProfile} from '../model/DivaProfile'; 4 | import {HttpParams} from '@angular/common/http'; 5 | import {AuthenticationService} from '../../../auth/authentication.service'; 6 | import {MessageService} from '../../../message.service'; 7 | 8 | @Component({ 9 | selector: 'app-diva-profile', 10 | templateUrl: './diva-profile.component.html', 11 | styleUrls: ['./diva-profile.component.css'] 12 | }) 13 | export class DivaProfileComponent implements OnInit { 14 | 15 | profile: DivaProfile; 16 | 17 | constructor( 18 | private api: ApiService, 19 | private auth: AuthenticationService, 20 | private messageService: MessageService 21 | ) { 22 | } 23 | 24 | ngOnInit() { 25 | const pdId = String(this.auth.currentUserValue.extId); 26 | const param = new HttpParams().set('pdId', pdId); 27 | this.api.get('api/game/diva/playerInfo', param).subscribe( 28 | data => this.profile = data, 29 | error => this.messageService.notice(error) 30 | ); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-pv-record/diva-pv-record.component.css: -------------------------------------------------------------------------------- 1 | mat-card-title { 2 | font-size: 1.2em; 3 | display: flex; 4 | } 5 | 6 | .level { 7 | margin-left: auto; 8 | } 9 | 10 | .song-info .info { 11 | color: #cfcfcf; 12 | } 13 | 14 | .result-content { 15 | display: flex; 16 | } 17 | 18 | .result-content .left { 19 | min-width: 30%; 20 | text-align: center; 21 | margin: 10px auto; 22 | } 23 | 24 | .score-rank-icon { 25 | font-size: 1.4rem; 26 | } 27 | 28 | .score-value { 29 | font-size: 1.4rem; 30 | } 31 | 32 | .rank-value { 33 | font-size: 1rem; 34 | } 35 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-pv-record/diva-pv-record.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 |
{{item.songInfo != null ? item.songInfo.songName : 'pvId:' + item.pvId}}
5 |
6 | {{item.edition === 1 ? edition[item.edition] : ''}} 7 | {{difficulty[item.difficulty]}} 8 |
9 |
10 | 11 |
12 | {{item.songInfo != null ? 'Lyric: ' + item.songInfo.lyrics + ' Song: ' + item.songInfo.music : ''}} 14 |
15 |
16 |
17 |
18 | {{result[item.result]}} 19 |
20 |
21 | Achievement:
22 | {{item.maxAttain|divaDecimal}}% 23 |
24 |
25 | Score:
26 | {{item.maxScore}} 27 |
28 |
29 |
30 |
31 | 32 | 33 | 34 |
35 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-pv-record/diva-pv-record.component.spec.ts: -------------------------------------------------------------------------------- 1 | import {async, ComponentFixture, TestBed} from '@angular/core/testing'; 2 | 3 | import {DivaPvRecordComponent} from './diva-pv-record.component'; 4 | 5 | describe('DivaPvRecordComponent', () => { 6 | let component: DivaPvRecordComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [DivaPvRecordComponent] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(DivaPvRecordComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-pv-record/diva-pv-record.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | import {ApiService} from '../../../api.service'; 3 | import {AuthenticationService} from '../../../auth/authentication.service'; 4 | import {MessageService} from '../../../message.service'; 5 | import {HttpParams} from '@angular/common/http'; 6 | import {Difficulty, DivaPvRecord, Edition, Result} from '../model/DivaPvRecord'; 7 | import {NgxIndexedDBService} from 'ngx-indexed-db'; 8 | import {DivaPv} from '../model/DivaPv'; 9 | 10 | @Component({ 11 | selector: 'app-diva-pv-record', 12 | templateUrl: './diva-pv-record.component.html', 13 | styleUrls: ['./diva-pv-record.component.css'] 14 | }) 15 | export class DivaPvRecordComponent implements OnInit { 16 | 17 | edition = Edition; 18 | difficulty = Difficulty; 19 | result = Result; 20 | 21 | pvRecords: DivaPvRecord[] = []; 22 | 23 | currentPage = 0; 24 | totalPages = 0; 25 | 26 | constructor( 27 | private api: ApiService, 28 | private auth: AuthenticationService, 29 | private messageService: MessageService, 30 | private dbService: NgxIndexedDBService 31 | ) { 32 | } 33 | 34 | ngOnInit() { 35 | this.load(); 36 | } 37 | 38 | load() { 39 | const pdId = String(this.auth.currentUserValue.extId); 40 | const param = new HttpParams().set('pdId', pdId).set('page', String(this.currentPage)); 41 | this.api.get('api/game/diva/pvRecord', param).subscribe( 42 | data => { 43 | if (data.content.length === 0) { 44 | this.messageService.notice('No more record'); 45 | return; 46 | } 47 | this.currentPage = data.page + 1; 48 | this.totalPages = data.totalPages; 49 | data.content.forEach(x => { 50 | this.pvRecords.push(x); 51 | }); 52 | this.pvRecords.forEach(x => { 53 | if (!x.songInfo) { 54 | this.dbService.getByID('divaPv', x.pvId).then( 55 | m => x.songInfo = m 56 | ); 57 | } 58 | }); 59 | }, 60 | error => this.messageService.notice(error) 61 | ); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-pvlist/diva-pvlist.component.css: -------------------------------------------------------------------------------- 1 | table { 2 | width: 100%; 3 | } 4 | 5 | .mat-form-field { 6 | font-size: 14px; 7 | width: 100%; 8 | } 9 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-pvlist/diva-pvlist.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
PvId. {{element.pvId}} Name {{element.songName}} Eng. Name {{element.songNameEng}}
21 | 22 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-pvlist/diva-pvlist.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { DivaPvlistComponent } from './diva-pvlist.component'; 4 | 5 | describe('DivaPvlistComponent', () => { 6 | let component: DivaPvlistComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ DivaPvlistComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(DivaPvlistComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-pvlist/diva-pvlist.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit, ViewChild} from '@angular/core'; 2 | import {NgxIndexedDBService} from 'ngx-indexed-db'; 3 | import {DivaPv} from '../model/DivaPv'; 4 | import {MatPaginator} from '@angular/material/paginator'; 5 | import {MatTableDataSource} from '@angular/material/table'; 6 | 7 | @Component({ 8 | selector: 'app-diva-pvlist', 9 | templateUrl: './diva-pvlist.component.html', 10 | styleUrls: ['./diva-pvlist.component.css'] 11 | }) 12 | export class DivaPvlistComponent implements OnInit { 13 | 14 | dataSource = new MatTableDataSource(); 15 | pvList: DivaPv[] = []; 16 | displayedColumns: string[] = ['pvId', 'songName', 'songNameEng']; 17 | 18 | @ViewChild(MatPaginator, {static: true}) paginator: MatPaginator; 19 | 20 | constructor(private dbService: NgxIndexedDBService) { 21 | } 22 | 23 | ngOnInit() { 24 | this.dbService.getAll('divaPv').then( 25 | x => { 26 | x.forEach(y => this.pvList.push(y)); 27 | this.dataSource.data = this.pvList; 28 | } 29 | ); 30 | this.dataSource.paginator = this.paginator; 31 | } 32 | 33 | applyFilter(filterValue: string) { 34 | this.dataSource.filter = filterValue.trim().toLowerCase(); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-recent/diva-recent.component.css: -------------------------------------------------------------------------------- 1 | mat-card-title { 2 | font-size: 1.2em; 3 | text-align: right; 4 | } 5 | 6 | .song-header { 7 | display: flex; 8 | } 9 | 10 | .song-header .level { 11 | margin-left: auto; 12 | font-size: 1.2em; 13 | } 14 | 15 | .song-info .title { 16 | font-size: 1.2em; 17 | } 18 | 19 | .song-info .info { 20 | color: #cfcfcf; 21 | } 22 | 23 | .result-content { 24 | display: flex; 25 | } 26 | 27 | .result-content .left { 28 | min-width: 40%; 29 | text-align: center; 30 | margin: auto; 31 | } 32 | 33 | .result-content .right { 34 | width: 100%; 35 | } 36 | 37 | .rank { 38 | font-size: 1rem; 39 | } 40 | 41 | .score-rank-icon { 42 | font-size: 1.3rem; 43 | } 44 | 45 | .score-value { 46 | font-size: 1.2rem; 47 | } 48 | 49 | .result-head { 50 | word-break: break-word; 51 | } 52 | 53 | .result-table tr th { 54 | width: 50%; 55 | } 56 | 57 | .result-table tr td:first-of-type { 58 | width: 20%; 59 | } 60 | 61 | .result-table tr td:last-of-type { 62 | width: 30%; 63 | } 64 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-recent/diva-recent.component.spec.ts: -------------------------------------------------------------------------------- 1 | import {async, ComponentFixture, TestBed} from '@angular/core/testing'; 2 | 3 | import {DivaRecentComponent} from './diva-recent.component'; 4 | 5 | describe('DivaRecentComponent', () => { 6 | let component: DivaRecentComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [DivaRecentComponent] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(DivaRecentComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-record-detail/diva-record-detail.component.css: -------------------------------------------------------------------------------- 1 | mat-card-title { 2 | font-size: 1.2em; 3 | display: flex; 4 | } 5 | 6 | mat-card-title button { 7 | margin-left: auto; 8 | } 9 | 10 | .song-info .info { 11 | color: #cfcfcf; 12 | } 13 | 14 | .result-content { 15 | display: flex; 16 | } 17 | 18 | .result-content .left { 19 | min-width: 30%; 20 | text-align: center; 21 | margin: 10px auto; 22 | } 23 | 24 | .score-rank-icon { 25 | font-size: 1.5rem; 26 | } 27 | 28 | .score-value { 29 | font-size: 1.4rem; 30 | } 31 | 32 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-record-detail/diva-record-detail.component.spec.ts: -------------------------------------------------------------------------------- 1 | import {async, ComponentFixture, TestBed} from '@angular/core/testing'; 2 | 3 | import {DivaRecordDetailComponent} from './diva-record-detail.component'; 4 | 5 | describe('DivaRecordDetailComponent', () => { 6 | let component: DivaRecordDetailComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [DivaRecordDetailComponent] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(DivaRecordDetailComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-setting/diva-display-setting/diva-display-setting.dialog.ts: -------------------------------------------------------------------------------- 1 | import {Component, Inject} from '@angular/core'; 2 | import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog'; 3 | 4 | @Component({ 5 | selector: 'diva-display-setting-dialog', 6 | templateUrl: 'diva-display-setting.html', 7 | }) 8 | export class DivaDisplaySettingDialog { 9 | 10 | // item: = this.data.commonModule : this.data.commonModule.split(',').map(x => Number(x)); 11 | 12 | constructor( 13 | public dialogRef: MatDialogRef, 14 | @Inject(MAT_DIALOG_DATA) public data: DivaDisplaySettingData) { 15 | } 16 | 17 | onNoClick(): void { 18 | this.dialogRef.close(); 19 | } 20 | 21 | } 22 | 23 | export interface DivaDisplaySettingData { 24 | showInterimRanking: boolean; 25 | showClearStatus: boolean; 26 | showGreatBorder: boolean; 27 | showExcellentBorder: boolean; 28 | showRivalBorder: boolean; 29 | showRgoSetting: boolean; 30 | } 31 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-setting/diva-display-setting/diva-display-setting.html: -------------------------------------------------------------------------------- 1 |

Change Display Setting

2 | 3 |
4 | Show Ranking 5 | Show Clear Status 6 | 7 | Show Great Border 8 | Show Excellent Border 9 | Show Rival Border 10 | Show Rhythm Game Option 11 |
12 |
13 |
14 | 15 | 16 |
17 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-setting/diva-mylist-setting/diva-mylist-setting.dialog.ts: -------------------------------------------------------------------------------- 1 | import {Component, Inject} from '@angular/core'; 2 | import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog'; 3 | 4 | @Component({ 5 | selector: 'diva-mylist-setting-dialog', 6 | templateUrl: 'diva-mylist-setting.html', 7 | }) 8 | export class DivaMylistSettingDialog { 9 | 10 | // item: = this.data.commonModule : this.data.commonModule.split(',').map(x => Number(x)); 11 | 12 | constructor( 13 | public dialogRef: MatDialogRef, 14 | @Inject(MAT_DIALOG_DATA) public data: DivaMylistSettingData) { 15 | } 16 | 17 | onNoClick(): void { 18 | this.dialogRef.close(); 19 | } 20 | 21 | } 22 | 23 | export interface DivaMylistSettingData { 24 | selector: string; 25 | myList0: string; 26 | myList1: string; 27 | myList2: string; 28 | } 29 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-setting/diva-mylist-setting/diva-mylist-setting.html: -------------------------------------------------------------------------------- 1 |

Change MyList

2 |
3 | Length is 40, so make sure there is 39 comma
4 | 5 | myList 6 | 7 | myList1 8 | myList2 9 | myList3 10 | 11 | 12 | 13 | myList1 14 | 15 | 16 | 17 | myList2 18 | 19 | 20 | 21 | myList3 22 | 23 | 24 |
25 |
26 | 27 | 28 |
29 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-setting/diva-name-setting/diva-name-setting.dialog.ts: -------------------------------------------------------------------------------- 1 | import {Component, Inject} from '@angular/core'; 2 | import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog'; 3 | 4 | @Component({ 5 | selector: 'diva-name-setting-dialog', 6 | templateUrl: 'diva-name-setting.html', 7 | }) 8 | export class DivaNameSettingDialog { 9 | 10 | constructor( 11 | public dialogRef: MatDialogRef, 12 | @Inject(MAT_DIALOG_DATA) public data: DivaNameSettingData) { 13 | } 14 | 15 | onNoClick(): void { 16 | this.dialogRef.close(); 17 | } 18 | 19 | } 20 | 21 | export interface DivaNameSettingData { 22 | playerName: string; 23 | } 24 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-setting/diva-name-setting/diva-name-setting.html: -------------------------------------------------------------------------------- 1 |

Change Player Name

2 |
3 | 4 | 5 | 6 |
7 |
8 | 9 | 10 |
11 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-setting/diva-plate-setting/diva-plate-setting.dialog.ts: -------------------------------------------------------------------------------- 1 | import {Component, Inject} from '@angular/core'; 2 | import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog'; 3 | 4 | @Component({ 5 | selector: 'diva-plate-setting-dialog', 6 | templateUrl: 'diva-plate-setting.html', 7 | }) 8 | export class DivaPlateSettingDialog { 9 | 10 | constructor( 11 | public dialogRef: MatDialogRef, 12 | @Inject(MAT_DIALOG_DATA) public data: DivaPlateSettingData) { 13 | } 14 | 15 | onNoClick(): void { 16 | this.dialogRef.close(); 17 | } 18 | 19 | } 20 | 21 | export interface DivaPlateSettingData { 22 | plateId: number; 23 | plateEffectId: number; 24 | } 25 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-setting/diva-plate-setting/diva-plate-setting.html: -------------------------------------------------------------------------------- 1 |

Change Plate

2 |
3 | 4 | Plate Id: 5 | 6 | 7 | 8 | Plate Effect Id: 9 | 10 | 11 |
12 |
13 | 14 | 15 |
16 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-setting/diva-rival-setting/diva-rival-setting.dialog.ts: -------------------------------------------------------------------------------- 1 | import {Component, Inject} from '@angular/core'; 2 | import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog'; 3 | 4 | @Component({ 5 | selector: 'diva-rival-setting-dialog', 6 | templateUrl: 'diva-rival-setting.html', 7 | }) 8 | export class DivaRivalSettingDialog { 9 | 10 | constructor( 11 | public dialogRef: MatDialogRef, 12 | @Inject(MAT_DIALOG_DATA) public data: DivaRivalSettingData) { 13 | } 14 | 15 | onNoClick(): void { 16 | this.dialogRef.close(); 17 | } 18 | 19 | } 20 | 21 | export interface DivaRivalSettingData { 22 | rivalId: number; 23 | } 24 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-setting/diva-rival-setting/diva-rival-setting.html: -------------------------------------------------------------------------------- 1 |

Set Rival

2 |
3 |

Ask your friend's Project DIVA ID or add rival at ranking page

4 | 5 | Rival PdId: 6 | 7 | 8 |
9 |
10 | 11 | 12 |
13 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-setting/diva-se-setting/diva-se-setting.dialog.ts: -------------------------------------------------------------------------------- 1 | import {Component, Inject} from '@angular/core'; 2 | import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog'; 3 | 4 | @Component({ 5 | selector: 'diva-se-setting-dialog', 6 | templateUrl: 'diva-se-setting.html', 7 | }) 8 | export class DivaSeSettingDialog { 9 | 10 | // item: = this.data.commonModule : this.data.commonModule.split(',').map(x => Number(x)); 11 | 12 | constructor( 13 | public dialogRef: MatDialogRef, 14 | @Inject(MAT_DIALOG_DATA) public data: DivaSeSettingData) { 15 | } 16 | 17 | onNoClick(): void { 18 | this.dialogRef.close(); 19 | } 20 | 21 | } 22 | 23 | export interface DivaSeSettingData { 24 | buttonSe: number; 25 | chainSlideSe: number; 26 | slideSe: number; 27 | sliderTouchSe: number; 28 | } 29 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-setting/diva-se-setting/diva-se-setting.html: -------------------------------------------------------------------------------- 1 |

Change Se

2 |
3 | Set to -1 if you want to disable 4 | 5 | Button Se 6 | 7 | 8 | 9 | Chain Slide Se 10 | 11 | 12 | 13 | Slide Se 14 | 15 | 16 | 17 | Slider Touch Se 18 | 19 | 20 |
21 |
22 | 23 | 24 |
25 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-setting/diva-setting.component.css: -------------------------------------------------------------------------------- 1 | mat-card-content { 2 | display: flex; 3 | } 4 | 5 | .content { 6 | word-break: break-all; 7 | word-break-cjk: break-all; 8 | width: 80%; 9 | } 10 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-setting/diva-setting.component.spec.ts: -------------------------------------------------------------------------------- 1 | import {async, ComponentFixture, TestBed} from '@angular/core/testing'; 2 | 3 | import {DivaSettingComponent} from './diva-setting.component'; 4 | 5 | describe('DivaSettingComponent', () => { 6 | let component: DivaSettingComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [DivaSettingComponent] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(DivaSettingComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-setting/diva-skin-setting/diva-skin-setting.dialog.ts: -------------------------------------------------------------------------------- 1 | import {Component, Inject} from '@angular/core'; 2 | import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog'; 3 | 4 | @Component({ 5 | selector: 'diva-skin-setting-dialog', 6 | templateUrl: 'diva-skin-setting.html', 7 | }) 8 | export class DivaSkinSettingDialog { 9 | 10 | constructor( 11 | public dialogRef: MatDialogRef, 12 | @Inject(MAT_DIALOG_DATA) public data: DivaSkinSettingData) { 13 | } 14 | 15 | onNoClick(): void { 16 | this.dialogRef.close(); 17 | } 18 | 19 | } 20 | 21 | export interface DivaSkinSettingData { 22 | skinId: number; 23 | } 24 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-setting/diva-skin-setting/diva-skin-setting.html: -------------------------------------------------------------------------------- 1 |

Change Skin

2 |
3 | 4 | Skin Id: 5 | 6 | 7 |
8 |
9 | 10 | 11 |
12 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-setting/diva-title-setting/diva-title-setting.dialog.ts: -------------------------------------------------------------------------------- 1 | import {Component, Inject} from '@angular/core'; 2 | import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog'; 3 | 4 | @Component({ 5 | selector: 'diva-title-setting-dialog', 6 | templateUrl: 'diva-title-setting.html', 7 | }) 8 | export class DivaTitleSettingDialog { 9 | 10 | constructor( 11 | public dialogRef: MatDialogRef, 12 | @Inject(MAT_DIALOG_DATA) public data: DivaTitleSettingData) { 13 | } 14 | 15 | onNoClick(): void { 16 | this.dialogRef.close(); 17 | } 18 | 19 | } 20 | 21 | export interface DivaTitleSettingData { 22 | title: string; 23 | } 24 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva-setting/diva-title-setting/diva-title-setting.html: -------------------------------------------------------------------------------- 1 |

Change Title

2 |
3 | 4 | 5 | 6 |
7 |
8 | 9 | 10 |
11 | -------------------------------------------------------------------------------- /src/app/sega/diva/diva.routing.ts: -------------------------------------------------------------------------------- 1 | import {RouterModule, Routes} from '@angular/router'; 2 | import {DivaProfileComponent} from './diva-profile/diva-profile.component'; 3 | import {DivaRecentComponent} from './diva-recent/diva-recent.component'; 4 | import {DivaSettingComponent} from './diva-setting/diva-setting.component'; 5 | import {DivaPvRecordComponent} from './diva-pv-record/diva-pv-record.component'; 6 | import {DivaRecordDetailComponent} from './diva-record-detail/diva-record-detail.component'; 7 | import {DivaManagementComponent} from './diva-management/diva-management/diva-management.component'; 8 | import {DivaFestaComponent} from './diva-management/diva-festa/diva-festa.component'; 9 | import {DivaFestaEditComponent} from './diva-management/diva-festa/diva-festa-edit/diva-festa-edit.component'; 10 | import {DivaContestComponent} from './diva-management/diva-contest/diva-contest.component'; 11 | import {DivaContestEditComponent} from './diva-management/diva-contest/diva-contest-edit/diva-contest-edit.component'; 12 | import {DivaModulesComponent} from './diva-modules/diva-modules.component'; 13 | import {DivaNewsComponent} from './diva-management/diva-news/diva-news.component'; 14 | import {DivaCustomizeComponent} from './diva-customize/diva-customize.component'; 15 | import {DivaPvlistComponent} from './diva-pvlist/diva-pvlist.component'; 16 | 17 | const routes: Routes = [ 18 | {path: 'profile', component: DivaProfileComponent}, 19 | {path: 'record', component: DivaPvRecordComponent}, 20 | {path: 'record/:pvId', component: DivaRecordDetailComponent}, 21 | {path: 'recent', component: DivaRecentComponent}, 22 | {path: 'setting', component: DivaSettingComponent}, 23 | {path: 'management', component: DivaManagementComponent}, 24 | {path: 'management/festa', component: DivaFestaComponent}, 25 | {path: 'management/festa/edit', component: DivaFestaEditComponent}, 26 | {path: 'management/contest', component: DivaContestComponent}, 27 | {path: 'management/contest/edit', component: DivaContestEditComponent}, 28 | {path: 'management/news', component: DivaNewsComponent}, 29 | {path: 'modules', component: DivaModulesComponent}, 30 | {path: 'customizes', component: DivaCustomizeComponent}, 31 | {path: 'pv', component: DivaPvlistComponent}, 32 | ]; 33 | 34 | export const DivaRoutes = RouterModule.forChild(routes); 35 | -------------------------------------------------------------------------------- /src/app/sega/diva/model/DivaCustomize.ts: -------------------------------------------------------------------------------- 1 | export interface DivaCustomize { 2 | id: number; 3 | name: string; 4 | price: number; 5 | } 6 | -------------------------------------------------------------------------------- /src/app/sega/diva/model/DivaModule.ts: -------------------------------------------------------------------------------- 1 | export interface DivaModule { 2 | id: number; 3 | name: string; 4 | price: number; 5 | } 6 | -------------------------------------------------------------------------------- /src/app/sega/diva/model/DivaPlayLog.ts: -------------------------------------------------------------------------------- 1 | import {DivaPv} from './DivaPv'; 2 | import {Difficulty, Edition, Result} from './DivaPvRecord'; 3 | import {DivaModule} from './DivaModule'; 4 | 5 | export interface DivaPlayLog { 6 | id: number; 7 | pvId: number; 8 | songInfo?: DivaPv; 9 | difficulty: Difficulty; 10 | edition: Edition; 11 | scriptVer: number; 12 | score: number; 13 | challengeKind: number; 14 | challengeResult: number; 15 | clearResult: Result; 16 | vp: number; 17 | coolCount: number; 18 | coolPercent: number; 19 | fineCount: number; 20 | finePercent: number; 21 | safeCount: number; 22 | safePercent: number; 23 | sadCount: number; 24 | sadPercent: number; 25 | wrongCount: number; 26 | wrongPercent: number; 27 | maxCombo: number; 28 | chanceTime: number; 29 | holdScore: number; 30 | attainPoint: number; 31 | skinId: number; 32 | buttonSe: number; 33 | buttonSeVol: number; 34 | sliderSe: number; 35 | modules: string; 36 | modulesInfo?: DivaModule[]; 37 | stageCompletion: number; 38 | slideScore: number; 39 | isVocalChange: number; 40 | customizeItems: string; 41 | rhythmGameOptions: string; 42 | screenShotCount: number; 43 | dateTime: Date; 44 | chainSlideSe: number; 45 | sliderTouchSe: number; 46 | } 47 | -------------------------------------------------------------------------------- /src/app/sega/diva/model/DivaProfile.ts: -------------------------------------------------------------------------------- 1 | export interface DivaProfile { 2 | pdId: number; 3 | playerName: string; 4 | vocaloidPoints: number; 5 | level: number; 6 | levelExp: number; 7 | levelTitle: string; 8 | plateId: number; 9 | plateEffectId: number; 10 | passwordStatus: number; 11 | preferPerPvModule: boolean; 12 | preferCommonModule: boolean; 13 | usePerPvSkin: boolean; 14 | usePerPvButtonSe: boolean; 15 | usePerPvSliderSe: boolean; 16 | usePerPvChainSliderSe: boolean; 17 | usePerPvTouchSliderSe: boolean; 18 | commonModule: string; 19 | commonCustomizeItems: string; 20 | commonModuleSetTime: Date; 21 | moduleSelectItemFlag: string; 22 | commonSkin: number; 23 | headphoneVolume: number; 24 | buttonSeOn: boolean; 25 | buttonSeVolume: number; 26 | sliderSeVolume: number; 27 | buttonSe: number; 28 | chainSlideSe: number; 29 | slideSe: number; 30 | sliderTouchSe: number; 31 | sortMode: number; 32 | showInterimRanking: boolean; 33 | showClearStatus: boolean; 34 | showGreatBorder: boolean; 35 | showExcellentBorder: boolean; 36 | showRivalBorder: boolean; 37 | showRgoSetting: boolean; 38 | myList0: string; 39 | myList1: string; 40 | myList2: string; 41 | } 42 | -------------------------------------------------------------------------------- /src/app/sega/diva/model/DivaPv.ts: -------------------------------------------------------------------------------- 1 | export interface DivaPv { 2 | pvId: number; 3 | bpm: number; 4 | date: string; 5 | songName: string; 6 | songNameEng?: string; 7 | songNameReading?: string; 8 | arranger?: string; 9 | illustrator?: string; 10 | lyrics?: string; 11 | music?: string; 12 | difficulty?: DivaPvDiffSet; 13 | performerNumber: number; 14 | } 15 | 16 | export interface DivaDifficulty { 17 | edition: number; 18 | level: string; 19 | version: number; 20 | } 21 | 22 | export interface DivaPvDiffSet { 23 | easy?: DivaDifficulty; 24 | normal?: DivaDifficulty; 25 | hard?: DivaDifficulty; 26 | extreme?: DivaDifficulty; 27 | extreme_extra?: DivaDifficulty; 28 | } 29 | -------------------------------------------------------------------------------- /src/app/sega/diva/model/DivaPvRecord.ts: -------------------------------------------------------------------------------- 1 | import {DivaPv} from './DivaPv'; 2 | 3 | export interface DivaPvRecord { 4 | x: unknown; 5 | pvId: number; 6 | songInfo?: DivaPv; 7 | edition: Edition; 8 | difficulty: Difficulty; 9 | result: Result; 10 | maxScore: number; 11 | maxAttain: number; 12 | challengeKind: number; 13 | rgoPurchased: string; 14 | rgoPlayed: string; 15 | } 16 | 17 | export enum Edition { 18 | Original, 19 | Extra 20 | } 21 | 22 | export enum Difficulty { 23 | UNDEFINED = -1, 24 | Easy = 0, 25 | Normal = 1, 26 | Hard = 2, 27 | Extreme = 3, 28 | } 29 | 30 | export enum Result { 31 | NO_CLEAR = -1, 32 | MISS_TAKE = 0, 33 | CHEAP = 1, 34 | STANDARD = 2, 35 | GREAT = 3, 36 | EXCELLENT = 4, 37 | PERFECT = 5 38 | } 39 | -------------------------------------------------------------------------------- /src/app/sega/diva/model/DivaRankingRecord.ts: -------------------------------------------------------------------------------- 1 | export interface DivaRankingRecord { 2 | id: number; 3 | playerName: string; 4 | score: number; 5 | attain: number; 6 | } 7 | -------------------------------------------------------------------------------- /src/app/sega/diva/model/DivaRecordDetail.ts: -------------------------------------------------------------------------------- 1 | import {DivaPvRecord} from './DivaPvRecord'; 2 | import {DivaPv} from './DivaPv'; 3 | import {DivaModule} from './DivaModule'; 4 | 5 | export interface DivaRecordDetail { 6 | songInfo?: DivaPv; 7 | records: DivaPvRecord[]; 8 | customize?: DivaPvCustomize; 9 | } 10 | 11 | export interface DivaPvCustomize { 12 | pvId: number; 13 | module: string; 14 | modulesInfo?: DivaModule[]; 15 | customize: string; 16 | customizeFlag: string; 17 | skin: number; 18 | buttonSe: number; 19 | slideSe: number; 20 | chainSlideSe: number; 21 | sliderTouchSe: number; 22 | } 23 | -------------------------------------------------------------------------------- /src/app/sega/diva/model/Page.ts: -------------------------------------------------------------------------------- 1 | export interface Page { 2 | content: T[]; 3 | page: number; 4 | totalPages: number; 5 | totalElements: number; 6 | } 7 | -------------------------------------------------------------------------------- /src/app/sega/diva/model/mannagement/Festa.ts: -------------------------------------------------------------------------------- 1 | import {Difficulty} from '../DivaPvRecord'; 2 | 3 | export interface Festa { 4 | id: number; 5 | enable: boolean; 6 | name: string; 7 | kind: FestaKind; 8 | difficulty: Difficulty; 9 | pvList: string; 10 | attributes: string; 11 | addVP: number; 12 | vpMultiplier: number; 13 | start: Date; 14 | end: Date; 15 | createDate: Date; 16 | } 17 | 18 | export enum FestaKind { 19 | PinkFesta = 0, 20 | GreenFesta = 1, 21 | } 22 | -------------------------------------------------------------------------------- /src/app/sega/diva/model/mannagement/contest.ts: -------------------------------------------------------------------------------- 1 | export interface Contest { 2 | id: number; 3 | enable: boolean; 4 | startTime: Date; 5 | endTime: Date; 6 | name: string; 7 | description: string; 8 | league: ContestLeague; 9 | stars: number; 10 | minComplexity: number; 11 | maxComplexity: number; 12 | stages: number; 13 | stageLimit: ContestStageLimit; 14 | normaType: ContestNormaType; 15 | bronzeBorders: number; 16 | sliverBorders: number; 17 | goldBorders: number; 18 | pvList?: string; 19 | pvDiffList?: string; 20 | bronzeContestReward?: string; 21 | sliverContestReward?: string; 22 | goldContestReward?: string; 23 | contestEntryReward?: string; 24 | } 25 | 26 | export enum ContestLeague { 27 | Beginner = 0, 28 | Intermediate = 1, 29 | Advanced = 2, 30 | Professional = 3, 31 | } 32 | 33 | export enum ContestStageLimit { 34 | Unlimited = 0, 35 | Limited = 1, 36 | } 37 | 38 | export enum ContestNormaType { 39 | Score = 0, 40 | Percentage = 1, 41 | CoolPercentage = 2, 42 | } 43 | -------------------------------------------------------------------------------- /src/app/sega/diva/util/diva-decimal.pipe.ts: -------------------------------------------------------------------------------- 1 | import {Pipe, PipeTransform} from '@angular/core'; 2 | 3 | @Pipe({ 4 | name: 'divaDecimal' 5 | }) 6 | export class DivaDecimalPipe implements PipeTransform { 7 | 8 | transform(num: number): string { 9 | return String(num / 100); 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/model/OngekiCard.ts: -------------------------------------------------------------------------------- 1 | import {OngekiSkill} from './OngekiSkill'; 2 | import {OngekiCharacter} from './OngekiCharacter'; 3 | 4 | export interface OngekiCard { 5 | id: number; 6 | name: string; 7 | nickName: string; 8 | attribute: string; 9 | charaId: number; 10 | characterInfo?: OngekiCharacter; 11 | school: string; 12 | gakunen: string; 13 | rarity: string; 14 | levelParam: string; 15 | skillId: number; 16 | skillInfo?: OngekiSkill; 17 | choKaikaSkillId: number; 18 | choKaikaSkillInfo?: OngekiSkill; 19 | cardNumber: string; 20 | version: string; 21 | } 22 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/model/OngekiCharacter.ts: -------------------------------------------------------------------------------- 1 | export interface OngekiCharacter { 2 | id: number; 3 | name: string; 4 | cv: string; 5 | modelId: number; 6 | } 7 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/model/OngekiEnums.ts: -------------------------------------------------------------------------------- 1 | export enum Difficulty { 2 | Basic, 3 | Advanced, 4 | Expert, 5 | Master, 6 | Lunatic, 7 | Max, 8 | } 9 | 10 | export enum PlayResult { 11 | Failed, 12 | Finish, 13 | Clear, 14 | Max 15 | } 16 | 17 | export enum NotesComboResult { 18 | None, 19 | FullCombo, 20 | AllBreak, 21 | Max, 22 | } 23 | 24 | export enum BellComboResult { 25 | None, 26 | FullBell, 27 | Max, 28 | } 29 | 30 | export enum RetireResult { 31 | None, 32 | NoLife, 33 | ScoreRetire, 34 | DeathSkill, 35 | Max, 36 | } 37 | 38 | export enum BattleRank { 39 | Invalid = -1, 40 | Begin = 0, 41 | None = 0, 42 | Fuka = 1, 43 | Ka = 2, 44 | Ryo = 3, 45 | Yu = 4, 46 | Shu = 5, 47 | Goku = 6, 48 | Goku1 = 7, 49 | Goku2 = 8, 50 | Goku3 = 9, 51 | Goku4 = 10, 52 | Goku5 = 11, 53 | End = 12, 54 | } 55 | 56 | export enum TechnicalRank { 57 | Invalid = -1, 58 | Begin = 0, 59 | None = 0, 60 | D = 1, 61 | C = 2, 62 | B = 3, 63 | BB = 4, 64 | BBB = 5, 65 | A = 6, 66 | AA = 7, 67 | AAA = 8, 68 | S = 9, 69 | SS = 10, 70 | SSS = 11, 71 | SSS1 = 12, 72 | End = 13, 73 | } 74 | 75 | // The AttributeType send by client is + 1. So the value here is start from 1 76 | export enum AttributeType { 77 | Fire = 1, 78 | Aqua = 2, 79 | Leaf = 3, 80 | Max = 4 81 | } 82 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/model/OngekiMusic.ts: -------------------------------------------------------------------------------- 1 | export interface OngekiMusic { 2 | id: number; 3 | name: string; 4 | sortName: string; 5 | artistName: string; 6 | genre: string; 7 | bossCardId: number; 8 | bossLevel: number; 9 | level0: string; 10 | level1: string; 11 | level2: string; 12 | level3: string; 13 | level4: string; 14 | } 15 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/model/OngekiProfile.ts: -------------------------------------------------------------------------------- 1 | import {OngekiCard} from './OngekiCard'; 2 | import {OngekiCharacter} from './OngekiCharacter'; 3 | 4 | export interface DisplayOngekiProfile { 5 | userName: string; 6 | level: number; 7 | exp: number; 8 | point: number; 9 | totalPoint: number; 10 | playCount: number; 11 | jewelCount: number; 12 | totalJewelCount: number; 13 | playerRating: number; 14 | highestRating: number; 15 | battlePoint: number; 16 | nameplateId: number; 17 | trophyId: number; 18 | cardId: number; 19 | card?: OngekiCard; 20 | characterId: number; 21 | character: OngekiCharacter; 22 | sumTechHighScore: number; 23 | sumTechBasicHighScore: number; 24 | sumTechAdvancedHighScore: number; 25 | sumTechExpertHighScore: number; 26 | sumTechMasterHighScore: number; 27 | sumTechLunaticHighScore: number; 28 | sumBattleHighScore: number; 29 | sumBattleBasicHighScore: number; 30 | sumBattleAdvancedHighScore: number; 31 | sumBattleExpertHighScore: number; 32 | sumBattleMasterHighScore: number; 33 | sumBattleLunaticHighScore: number; 34 | } 35 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/model/OngekiSkill.ts: -------------------------------------------------------------------------------- 1 | export interface OngekiSkill { 2 | id: number; 3 | name: string; 4 | category: string; 5 | info: string; 6 | } 7 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/model/PlayerCard.ts: -------------------------------------------------------------------------------- 1 | import {OngekiCard} from './OngekiCard'; 2 | import {OngekiCharacter} from './OngekiCharacter'; 3 | import {OngekiSkill} from './OngekiSkill'; 4 | 5 | export interface PlayerCard { 6 | cardId: number; 7 | digitalStock: number; 8 | analogStock: number; 9 | level: number; 10 | maxLevel: number; 11 | exp: number; 12 | printCount: number; 13 | useCount: number; 14 | kaikaDate: string; 15 | choKaikaDate: string; 16 | skillId: number; 17 | created: string; 18 | isNew: boolean; 19 | isAcquired: boolean; 20 | cardInfo?: OngekiCard; 21 | characterInfo?: OngekiCharacter; 22 | skillInfo?: OngekiSkill; 23 | } 24 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/model/PlayerPlaylog.ts: -------------------------------------------------------------------------------- 1 | import {OngekiMusic} from './OngekiMusic'; 2 | import {OngekiCard} from './OngekiCard'; 3 | import {OngekiCharacter} from './OngekiCharacter'; 4 | 5 | export interface PlayerPlaylog { 6 | sortNumber: number; 7 | placeId: number; 8 | placeName: string; 9 | playDate: string; 10 | userPlayDate: string; 11 | musicId: number; 12 | songInfo: OngekiMusic; 13 | level: number; 14 | playKind: number; 15 | eventId: number; 16 | eventName: string; 17 | eventPoint: number; 18 | playedUserId1: number; 19 | playedUserId2: number; 20 | playedUserId3: number; 21 | playedUserName1: string; 22 | playedUserName2: string; 23 | playedUserName3: string; 24 | playedMusicLevel1: number; 25 | playedMusicLevel2: number; 26 | playedMusicLevel3: number; 27 | cardId1: number; 28 | cardId2: number; 29 | cardId3: number; 30 | cardLevel1: number; 31 | cardLevel2: number; 32 | cardLevel3: number; 33 | cardAttack1: number; 34 | cardAttack2: number; 35 | cardAttack3: number; 36 | cardInfo1?: OngekiCard; 37 | cardInfo2?: OngekiCard; 38 | cardInfo3?: OngekiCard; 39 | bossCharaId: number; 40 | bossLevel: number; 41 | bossAttribute: number; 42 | bossCharaInfo?: OngekiCharacter; 43 | clearStatus: number; 44 | techScore: number; 45 | techScoreRank: number; 46 | battleScore: number; 47 | battleScoreRank: number; 48 | maxCombo: number; 49 | judgeMiss: number; 50 | judgeHit: number; 51 | judgeBreak: number; 52 | judgeCriticalBreak: number; 53 | rateTap: number; 54 | rateHold: number; 55 | rateFlick: number; 56 | rateSideTap: number; 57 | rateSideHold: number; 58 | bellCount: number; 59 | totalBellCount: number; 60 | damageCount: number; 61 | overDamage: number; 62 | playerRating: number; 63 | battlePoint: number; 64 | isFullCombo: boolean; 65 | isOverDamageNewRecord: boolean; 66 | isFullBell: boolean; 67 | isTechNewRecord: boolean; 68 | isAllBreak: boolean; 69 | isBattleNewRecord: boolean; 70 | } 71 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/model/PlayerRatingItem.ts: -------------------------------------------------------------------------------- 1 | import {OngekiMusic} from './OngekiMusic'; 2 | import {OngekiCard} from './OngekiCard'; 3 | 4 | export interface PlayerRatingItem { 5 | musicId: number; 6 | level: number; 7 | value: number; 8 | musicInfo?: OngekiMusic; 9 | bossCardInfo?: OngekiCard; 10 | } 11 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/ongeki-battle-point/ongeki-battle-point.component.css: -------------------------------------------------------------------------------- 1 | .battle-point-table { 2 | width: 100%; 3 | text-align: center; 4 | } 5 | 6 | .battle-point-table th { 7 | text-align: center; 8 | } 9 | 10 | .battle-point-table h3 { 11 | font-size: 20px; 12 | text-align: center; 13 | } 14 | 15 | .battle-point-table img { 16 | width: 24px; 17 | height: 24px; 18 | padding: 0 0 0 6px; 19 | } 20 | 21 | .battle-point-table td { 22 | max-width: 130px; 23 | } 24 | 25 | .music-title { 26 | text-align: left; 27 | } 28 | 29 | @media only screen and (max-width: 599px) { 30 | .battle-point-table table { 31 | font-size: 12px; 32 | } 33 | 34 | .battle-point-table img { 35 | width: 18px; 36 | height: 18px; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/ongeki-battle-point/ongeki-battle-point.component.html: -------------------------------------------------------------------------------- 1 | 2 | Battle Point 3 | 4 | 5 | 6 | 7 | Current Battle Point: {{profile ? profile.battlePoint : ''}} 8 | 9 | 10 | 11 | 12 |

Best Battle Points

13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 26 | 29 | 32 | 35 | 36 | 37 |
MusicLevelPointAttr.
23 | 24 | {{i + 1}}: {{item.musicInfo ? item.musicInfo.name : 'MusicID:' + item.musicId}} 25 | 27 | {{difficulty[item.level]}} 28 | 30 | {{item.value}} 31 | 33 | {{item.bossCardInfo ? item.bossCardInfo.attribute : 'Unknown' }} 34 |
38 |
39 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/ongeki-battle-point/ongeki-battle-point.component.spec.ts: -------------------------------------------------------------------------------- 1 | import {async, ComponentFixture, TestBed} from '@angular/core/testing'; 2 | 3 | import {OngekiBattlePointComponent} from './ongeki-battle-point.component'; 4 | 5 | describe('OngekiBattlePointComponent', () => { 6 | let component: OngekiBattlePointComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [OngekiBattlePointComponent] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(OngekiBattlePointComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/ongeki-card-gacha/ongeki-card-gacha.component.spec.ts: -------------------------------------------------------------------------------- 1 | import {async, ComponentFixture, TestBed} from '@angular/core/testing'; 2 | 3 | import {OngekiCardGachaComponent} from './ongeki-card-gacha.component'; 4 | 5 | describe('OngekiCardGachaComponent', () => { 6 | let component: OngekiCardGachaComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [OngekiCardGachaComponent] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(OngekiCardGachaComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/ongeki-card-list/ongeki-card-list.component.css: -------------------------------------------------------------------------------- 1 | .card-display { 2 | display: flex; 3 | } 4 | 5 | .card-display .image { 6 | max-width: 30%; 7 | } 8 | 9 | .card-display .image img { 10 | width: 100%; 11 | } 12 | 13 | .card-display .content { 14 | margin: 0 auto; 15 | width: 65%; 16 | } 17 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/ongeki-card-list/ongeki-card-list.component.html: -------------------------------------------------------------------------------- 1 | 2 | All Card List 3 | 4 | 5 | 6 | 7 | {{item.name}} 8 | 9 | 10 |
11 |
12 | 13 | 14 | 15 |
16 | {{item.characterInfo.name}}
17 | {{item.characterInfo.cv ? '(CV: ' + item.characterInfo.cv + ')' : ''}} 18 |
19 |
20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 |
Card ID{{item.id}}
Rarity{{item.rarity}}
Card Name{{item.nickName}}
Attribute{{item.attribute}}
School{{item.school}}
Gakunen{{item.gakunen}}
Skill{{item.skillInfo ? item.skillInfo.name : 'ID:' + item.skillId}}
ChoKaika Skill{{item.choKaikaSkillInfo ? item.choKaikaSkillInfo.name : 'ID:' + item.choKaikaSkillId}}
CardNumber{{item.cardNumber}}
59 |
60 |
61 |
62 | 63 |
64 | 65 |
66 |
67 | 70 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/ongeki-card-list/ongeki-card-list.component.spec.ts: -------------------------------------------------------------------------------- 1 | import {async, ComponentFixture, TestBed} from '@angular/core/testing'; 2 | 3 | import {OngekiCardListComponent} from './ongeki-card-list.component'; 4 | 5 | describe('OngekiCardListComponent', () => { 6 | let component: OngekiCardListComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [OngekiCardListComponent] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(OngekiCardListComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/ongeki-card-list/ongeki-card-list.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | import {ApiService} from '../../../api.service'; 3 | import {AuthenticationService} from '../../../auth/authentication.service'; 4 | import {MessageService} from '../../../message.service'; 5 | import {NgxIndexedDBService} from 'ngx-indexed-db'; 6 | import {environment} from '../../../../environments/environment'; 7 | import {OngekiCard} from '../model/OngekiCard'; 8 | import {OngekiSkill} from '../model/OngekiSkill'; 9 | import {OngekiCharacter} from '../model/OngekiCharacter'; 10 | 11 | @Component({ 12 | selector: 'app-ongeki-card-list', 13 | templateUrl: './ongeki-card-list.component.html', 14 | styleUrls: ['./ongeki-card-list.component.css'] 15 | }) 16 | export class OngekiCardListComponent implements OnInit { 17 | 18 | host = environment.assetsHost; 19 | 20 | cardList: OngekiCard[] = []; 21 | 22 | p = 1; 23 | 24 | constructor( 25 | private api: ApiService, 26 | private auth: AuthenticationService, 27 | private messageService: MessageService, 28 | private dbService: NgxIndexedDBService 29 | ) { 30 | } 31 | 32 | ngOnInit() { 33 | this.dbService.getAll('ongekiCard').then( 34 | x => x.forEach(y => { 35 | this.dbService.getByID('ongekiCharacter', y.charaId).then(z => y.characterInfo = z); 36 | this.dbService.getByID('ongekiSkill', y.skillId).then(z => y.skillInfo = z); 37 | this.dbService.getByID('ongekiSkill', y.choKaikaSkillId).then(z => y.choKaikaSkillInfo = z); 38 | this.cardList.push(y); 39 | }) 40 | ); 41 | } 42 | 43 | insertCard(cardId: number) { 44 | const aimeId = this.auth.currentUserValue.extId; 45 | this.api.post('api/game/ongeki/card', { 46 | aimeId, 47 | cardId 48 | }).subscribe( 49 | data => this.messageService.notice('Successful, go to check your card list'), 50 | error => this.messageService.notice(error) 51 | ); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/ongeki-card/ongeki-card.component.css: -------------------------------------------------------------------------------- 1 | .hint { 2 | color: #cfcfcf; 3 | } 4 | 5 | .action { 6 | text-align: right; 7 | } 8 | 9 | .card-display { 10 | display: flex; 11 | } 12 | 13 | .card-display .image { 14 | max-width: 30%; 15 | } 16 | 17 | .card-display .image img { 18 | width: 100%; 19 | } 20 | 21 | .card-display .content { 22 | margin: 0 auto; 23 | width: 65%; 24 | } 25 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/ongeki-card/ongeki-card.component.spec.ts: -------------------------------------------------------------------------------- 1 | import {async, ComponentFixture, TestBed} from '@angular/core/testing'; 2 | 3 | import {OngekiCardComponent} from './ongeki-card.component'; 4 | 5 | describe('OngekiCardComponent', () => { 6 | let component: OngekiCardComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [OngekiCardComponent] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(OngekiCardComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/ongeki-profile/ongeki-profile.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samnyan/aqua-viewer/a718036ab6baa92d9aa469a9997b3c73e6d9bb1d/src/app/sega/ongeki/ongeki-profile/ongeki-profile.component.css -------------------------------------------------------------------------------- /src/app/sega/ongeki/ongeki-profile/ongeki-profile.component.html: -------------------------------------------------------------------------------- 1 | 2 | Player Profile 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 |
Player Name{{profile.userName}}
Player Rating{{profile.playerRating / 100 | number: '1.2-2'}}
Player Highest Rating{{profile.highestRating / 100 | number: '1.2-2'}}
Battle Point{{profile.battlePoint}}
Player Level{{profile.level}}
Total Play Count{{profile.playCount}}
Name Plate Id{{profile.nameplateId}}
Card{{profile.card ? profile.card.name : 'ID:' + profile.cardId}}
Character{{profile.character ? profile.character.name : 'ID:' + profile.characterId}}
Total Tech High Score{{profile.sumTechHighScore}}
Total Battle High Score{{profile.sumBattleHighScore}}
50 |
51 |
52 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/ongeki-profile/ongeki-profile.component.spec.ts: -------------------------------------------------------------------------------- 1 | import {async, ComponentFixture, TestBed} from '@angular/core/testing'; 2 | 3 | import {OngekiProfileComponent} from './ongeki-profile.component'; 4 | 5 | describe('OngekiProfileComponent', () => { 6 | let component: OngekiProfileComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [OngekiProfileComponent] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(OngekiProfileComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/ongeki-profile/ongeki-profile.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | import {ApiService} from '../../../api.service'; 3 | import {AuthenticationService} from '../../../auth/authentication.service'; 4 | import {MessageService} from '../../../message.service'; 5 | import {HttpParams} from '@angular/common/http'; 6 | import {DisplayOngekiProfile} from '../model/OngekiProfile'; 7 | import {NgxIndexedDBService} from 'ngx-indexed-db'; 8 | import {OngekiCard} from '../model/OngekiCard'; 9 | import {OngekiCharacter} from '../model/OngekiCharacter'; 10 | 11 | @Component({ 12 | selector: 'app-ongeki-profile', 13 | templateUrl: './ongeki-profile.component.html', 14 | styleUrls: ['./ongeki-profile.component.css'] 15 | }) 16 | export class OngekiProfileComponent implements OnInit { 17 | 18 | profile: DisplayOngekiProfile; 19 | 20 | constructor( 21 | private api: ApiService, 22 | private auth: AuthenticationService, 23 | private messageService: MessageService, 24 | private dbService: NgxIndexedDBService 25 | ) { 26 | } 27 | 28 | ngOnInit() { 29 | const aimeId = String(this.auth.currentUserValue.extId); 30 | const param = new HttpParams().set('aimeId', aimeId); 31 | this.api.get('api/game/ongeki/profile', param).subscribe( 32 | data => { 33 | this.profile = data; 34 | this.dbService.getByID('ongekiCard', this.profile.cardId).then( 35 | x => this.profile.card = x 36 | ); 37 | this.dbService.getByID('ongekiCharacter', this.profile.characterId).then( 38 | x => this.profile.character = x 39 | ); 40 | }, 41 | error => this.messageService.notice(error) 42 | ); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/ongeki-rating/ongeki-rating.component.css: -------------------------------------------------------------------------------- 1 | .rating-info { 2 | font-size: 1.2em; 3 | } 4 | 5 | .battle-point-table { 6 | width: 100%; 7 | text-align: center; 8 | } 9 | 10 | .battle-point-table th { 11 | text-align: center; 12 | } 13 | 14 | .battle-point-table h3 { 15 | font-size: 20px; 16 | text-align: center; 17 | } 18 | 19 | .battle-point-table img { 20 | width: 24px; 21 | height: 24px; 22 | padding: 0 0 0 6px; 23 | } 24 | 25 | .battle-point-table td { 26 | max-width: 130px; 27 | } 28 | 29 | .music-title { 30 | text-align: left; 31 | } 32 | 33 | @media only screen and (max-width: 599px) { 34 | 35 | .battle-point-table img { 36 | width: 18px; 37 | height: 18px; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/ongeki-rating/ongeki-rating.component.spec.ts: -------------------------------------------------------------------------------- 1 | import {async, ComponentFixture, TestBed} from '@angular/core/testing'; 2 | 3 | import {OngekiRatingComponent} from './ongeki-rating.component'; 4 | 5 | describe('OngekiRatingComponent', () => { 6 | let component: OngekiRatingComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [OngekiRatingComponent] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(OngekiRatingComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/ongeki-recent/ongeki-recent.component.spec.ts: -------------------------------------------------------------------------------- 1 | import {async, ComponentFixture, TestBed} from '@angular/core/testing'; 2 | 3 | import {OngekiRecentComponent} from './ongeki-recent.component'; 4 | 5 | describe('OngekiRecentComponent', () => { 6 | let component: OngekiRecentComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [OngekiRecentComponent] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(OngekiRecentComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/ongeki-setting/ongeki-setting.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samnyan/aqua-viewer/a718036ab6baa92d9aa469a9997b3c73e6d9bb1d/src/app/sega/ongeki/ongeki-setting/ongeki-setting.component.css -------------------------------------------------------------------------------- /src/app/sega/ongeki/ongeki-setting/ongeki-setting.component.html: -------------------------------------------------------------------------------- 1 | 2 | ONGEKI Settings 3 | 4 | 5 | 6 | Export data 7 | 8 |
9 | Download 10 |
11 |
12 |
13 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/ongeki-setting/ongeki-setting.component.spec.ts: -------------------------------------------------------------------------------- 1 | import {async, ComponentFixture, TestBed} from '@angular/core/testing'; 2 | 3 | import {OngekiSettingComponent} from './ongeki-setting.component'; 4 | 5 | describe('OngekiSettingComponent', () => { 6 | let component: OngekiSettingComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [OngekiSettingComponent] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(OngekiSettingComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/ongeki-setting/ongeki-setting.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | import {ApiService} from '../../../api.service'; 3 | import {AuthenticationService} from '../../../auth/authentication.service'; 4 | import {MessageService} from '../../../message.service'; 5 | import {MatDialog} from '@angular/material/dialog'; 6 | import {HttpParams} from '@angular/common/http'; 7 | import {DisplayOngekiProfile} from '../model/OngekiProfile'; 8 | 9 | @Component({ 10 | selector: 'app-ongeki-setting', 11 | templateUrl: './ongeki-setting.component.html', 12 | styleUrls: ['./ongeki-setting.component.css'] 13 | }) 14 | export class OngekiSettingComponent implements OnInit { 15 | 16 | profile: DisplayOngekiProfile; 17 | 18 | aimeId: string; 19 | apiServer: string; 20 | 21 | constructor( 22 | private api: ApiService, 23 | private auth: AuthenticationService, 24 | private messageService: MessageService, 25 | public dialog: MatDialog 26 | ) { 27 | } 28 | 29 | ngOnInit(): void { 30 | this.aimeId = String(this.auth.currentUserValue.extId); 31 | this.apiServer = this.auth.currentUserValue.apiServer; 32 | const param = new HttpParams().set('aimeId', this.aimeId); 33 | this.api.get('api/game/ongeki/profile', param).subscribe( 34 | data => { 35 | this.profile = data; 36 | }, 37 | error => this.messageService.notice(error) 38 | ); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/ongeki-song-list/ongeki-song-list.component.css: -------------------------------------------------------------------------------- 1 | table { 2 | width: 100%; 3 | } 4 | 5 | .mat-form-field { 6 | font-size: 14px; 7 | width: 100%; 8 | } 9 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/ongeki-song-list/ongeki-song-list.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
Id. {{element.id}} Name {{element.name}} Artist {{element.artistName}}
21 | 22 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/ongeki-song-list/ongeki-song-list.component.spec.ts: -------------------------------------------------------------------------------- 1 | import {async, ComponentFixture, TestBed} from '@angular/core/testing'; 2 | 3 | import {OngekiSongListComponent} from './ongeki-song-list.component'; 4 | 5 | describe('OngekiSongListComponent', () => { 6 | let component: OngekiSongListComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [OngekiSongListComponent] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(OngekiSongListComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/ongeki-song-list/ongeki-song-list.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit, ViewChild} from '@angular/core'; 2 | import {NgxIndexedDBService} from 'ngx-indexed-db'; 3 | import {MatPaginator} from '@angular/material/paginator'; 4 | import {MatTableDataSource} from '@angular/material/table'; 5 | import {OngekiMusic} from '../model/OngekiMusic'; 6 | 7 | @Component({ 8 | selector: 'app-ongeki-song-list', 9 | templateUrl: './ongeki-song-list.component.html', 10 | styleUrls: ['./ongeki-song-list.component.css'] 11 | }) 12 | export class OngekiSongListComponent implements OnInit { 13 | 14 | dataSource = new MatTableDataSource(); 15 | songList: OngekiMusic[] = []; 16 | displayedColumns: string[] = ['id', 'name', 'artistName']; 17 | 18 | @ViewChild(MatPaginator, {static: true}) paginator: MatPaginator; 19 | 20 | constructor(private dbService: NgxIndexedDBService) { 21 | } 22 | 23 | ngOnInit() { 24 | this.dbService.getAll('ongekiMusic').then( 25 | x => { 26 | this.songList = x; 27 | this.dataSource.data = this.songList; 28 | } 29 | ); 30 | this.dataSource.paginator = this.paginator; 31 | } 32 | 33 | applyFilter(filterValue: string) { 34 | this.dataSource.filter = filterValue.trim().toLowerCase(); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/ongeki.routing.ts: -------------------------------------------------------------------------------- 1 | import {RouterModule, Routes} from '@angular/router'; 2 | import {OngekiProfileComponent} from './ongeki-profile/ongeki-profile.component'; 3 | import {OngekiCardComponent} from './ongeki-card/ongeki-card.component'; 4 | import {OngekiCardListComponent} from './ongeki-card-list/ongeki-card-list.component'; 5 | import {OngekiRecentComponent} from './ongeki-recent/ongeki-recent.component'; 6 | import {OngekiSongListComponent} from './ongeki-song-list/ongeki-song-list.component'; 7 | import {OngekiBattlePointComponent} from './ongeki-battle-point/ongeki-battle-point.component'; 8 | import {OngekiRatingComponent} from './ongeki-rating/ongeki-rating.component'; 9 | import {OngekiCardGachaComponent} from './ongeki-card-gacha/ongeki-card-gacha.component'; 10 | import {OngekiSettingComponent} from './ongeki-setting/ongeki-setting.component'; 11 | 12 | 13 | const routes: Routes = [ 14 | {path: 'profile', component: OngekiProfileComponent}, 15 | {path: 'recent', component: OngekiRecentComponent}, 16 | {path: 'song', component: OngekiSongListComponent}, 17 | {path: 'battle', component: OngekiBattlePointComponent}, 18 | {path: 'rating', component: OngekiRatingComponent}, 19 | {path: 'card', component: OngekiCardComponent}, 20 | {path: 'card/all', component: OngekiCardListComponent}, 21 | {path: 'card/gacha', component: OngekiCardGachaComponent}, 22 | {path: 'setting', component: OngekiSettingComponent}, 23 | ]; 24 | 25 | export const OngekiRoutes = RouterModule.forChild(routes); 26 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/util/to-attribute-class.pipe.spec.ts: -------------------------------------------------------------------------------- 1 | import {ToAttributeClassPipe} from './to-attribute-class.pipe'; 2 | 3 | describe('ToAttributeClassPipe', () => { 4 | it('create an instance', () => { 5 | const pipe = new ToAttributeClassPipe(); 6 | expect(pipe).toBeTruthy(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/util/to-attribute-class.pipe.ts: -------------------------------------------------------------------------------- 1 | import {Pipe, PipeTransform} from '@angular/core'; 2 | 3 | @Pipe({ 4 | name: 'toAttributeClass' 5 | }) 6 | export class ToAttributeClassPipe implements PipeTransform { 7 | 8 | transform(value: any): string { 9 | if (typeof value === 'string') { 10 | switch (value) { 11 | case 'Fire': 12 | return 'lv12'; 13 | case 'Aqua': 14 | return 'lv8'; 15 | case 'Leaf': 16 | return 'lv6'; 17 | case 'Max': 18 | return ''; 19 | } 20 | } 21 | if (typeof value === 'number') { 22 | switch (value) { 23 | // Start from 1 24 | case 1: 25 | return 'lv12'; 26 | case 2: 27 | return 'lv8'; 28 | case 3: 29 | return 'lv6'; 30 | case 4: 31 | return ''; 32 | } 33 | } 34 | return ''; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/util/to-battle-sprite.pipe.spec.ts: -------------------------------------------------------------------------------- 1 | import {ToBattleSpritePipe} from './to-battle-sprite.pipe'; 2 | 3 | describe('ToBattleSpritePipe', () => { 4 | it('create an instance', () => { 5 | const pipe = new ToBattleSpritePipe(); 6 | expect(pipe).toBeTruthy(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/util/to-battle-sprite.pipe.ts: -------------------------------------------------------------------------------- 1 | import {Pipe, PipeTransform} from '@angular/core'; 2 | import {BattleRank} from '../model/OngekiEnums'; 3 | 4 | @Pipe({ 5 | name: 'toBattleSprite' 6 | }) 7 | export class ToBattleSpritePipe implements PipeTransform { 8 | 9 | 10 | transform(value: number): string { 11 | switch (BattleRank[value]) { 12 | case 'Yu': 13 | return 'SB_RES_ScoreStamp_Great.png'; 14 | case 'Ryo': 15 | return 'SB_RES_ScoreStamp_Good.png'; 16 | case 'Fuka': 17 | return 'SB_RES_ScoreStamp_NoGood.png'; 18 | case 'Shu': 19 | return 'SB_RES_ScoreStamp_Excellent.png'; 20 | case 'Ka': 21 | return 'SB_RES_ScoreStamp_Usually.png'; 22 | case 'Goku': 23 | return 'SB_RES_ScoreStamp_Unbelievable.png'; 24 | case 'Goku1': 25 | return 'SB_RES_ScoreStamp_Unbelievable.png'; 26 | case 'Goku2': 27 | return 'SB_RES_ScoreStamp_Unbelievable.png'; 28 | case 'Goku3': 29 | return 'SB_RES_ScoreStamp_Unbelievable.png'; 30 | case 'Goku4': 31 | return 'SB_RES_ScoreStamp_Unbelievable.png'; 32 | case 'Goku5': 33 | return 'SB_RES_ScoreStamp_Unbelievable.png'; 34 | } 35 | return null; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/util/to-level-decimal.pipe.spec.ts: -------------------------------------------------------------------------------- 1 | import {ToLevelDecimalPipe} from './to-level-decimal.pipe'; 2 | 3 | describe('ToLevelDecimalPipe', () => { 4 | it('create an instance', () => { 5 | const pipe = new ToLevelDecimalPipe(); 6 | expect(pipe).toBeTruthy(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/util/to-level-decimal.pipe.ts: -------------------------------------------------------------------------------- 1 | import {Pipe, PipeTransform} from '@angular/core'; 2 | 3 | @Pipe({ 4 | name: 'toLevelDecimal' 5 | }) 6 | export class ToLevelDecimalPipe implements PipeTransform { 7 | 8 | transform(value: string): string { 9 | value = value.replace(',', '.'); 10 | if (value.charAt(value.length - 1) === '0' && value.charAt(value.length - 2) !== '.') { 11 | value = value.slice(0, value.length - 1); 12 | } 13 | return value; 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/util/to-tech-sprite.pipe.spec.ts: -------------------------------------------------------------------------------- 1 | import {ToTechSpritePipe} from './to-tech-sprite.pipe'; 2 | 3 | describe('ToTechSpritePipe', () => { 4 | it('create an instance', () => { 5 | const pipe = new ToTechSpritePipe(); 6 | expect(pipe).toBeTruthy(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /src/app/sega/ongeki/util/to-tech-sprite.pipe.ts: -------------------------------------------------------------------------------- 1 | import {Pipe, PipeTransform} from '@angular/core'; 2 | import {TechnicalRank} from '../model/OngekiEnums'; 3 | 4 | @Pipe({ 5 | name: 'toTechSprite' 6 | }) 7 | export class ToTechSpritePipe implements PipeTransform { 8 | 9 | transform(value: number): string { 10 | switch (TechnicalRank[value]) { 11 | case 'D': 12 | return 'SB_RES_ScoreRank_D.png'; 13 | case 'C': 14 | return 'SB_RES_ScoreRank_C.png'; 15 | case 'B': 16 | return 'SB_RES_ScoreRank_B.png'; 17 | case 'BB': 18 | return 'SB_RES_ScoreRank_BB.png'; 19 | case 'BBB': 20 | return 'SB_RES_ScoreRank_BBB.png'; 21 | case 'A': 22 | return 'SB_RES_ScoreRank_A.png'; 23 | case 'AA': 24 | return 'SB_RES_ScoreRank_AA.png'; 25 | case 'AAA': 26 | return 'SB_RES_ScoreRank_AAA.png'; 27 | case 'S': 28 | return 'SB_RES_ScoreRank_S.png'; 29 | case 'SS': 30 | return 'SB_RES_ScoreRank_SS.png'; 31 | case 'SSS': 32 | return 'SB_RES_ScoreRank_SSS.png'; 33 | case 'SSS1': 34 | return 'SB_RES_ScoreRank_SSS+.png'; 35 | } 36 | return null; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/app/util/formatnumber.pipe.spec.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable:no-unused-variable */ 2 | 3 | import {FormatnumberPipe} from './formatnumber.pipe'; 4 | 5 | describe('Pipe: Formatnumbere', () => { 6 | it('create an instance', () => { 7 | let pipe = new FormatnumberPipe(); 8 | expect(pipe).toBeTruthy(); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /src/app/util/formatnumber.pipe.ts: -------------------------------------------------------------------------------- 1 | import {Pipe, PipeTransform} from '@angular/core'; 2 | 3 | @Pipe({ 4 | name: 'formatNumber' 5 | }) 6 | export class FormatnumberPipe implements PipeTransform { 7 | 8 | public transform(value: number, length?: number): string { 9 | let str = value.toString(); 10 | while (str.length < length) { 11 | str = '0' + str; 12 | } 13 | return str; 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/app/util/tools.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {CommonModule} from '@angular/common'; 3 | import {FormatnumberPipe} from './formatnumber.pipe'; 4 | 5 | 6 | @NgModule({ 7 | declarations: [ 8 | FormatnumberPipe 9 | ], 10 | imports: [ 11 | CommonModule 12 | ], 13 | exports: [ 14 | FormatnumberPipe 15 | ] 16 | }) 17 | export class ToolsModule { 18 | } 19 | -------------------------------------------------------------------------------- /src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samnyan/aqua-viewer/a718036ab6baa92d9aa469a9997b3c73e6d9bb1d/src/assets/.gitkeep -------------------------------------------------------------------------------- /src/assets/icons/icon-128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samnyan/aqua-viewer/a718036ab6baa92d9aa469a9997b3c73e6d9bb1d/src/assets/icons/icon-128x128.png -------------------------------------------------------------------------------- /src/assets/icons/icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samnyan/aqua-viewer/a718036ab6baa92d9aa469a9997b3c73e6d9bb1d/src/assets/icons/icon-144x144.png -------------------------------------------------------------------------------- /src/assets/icons/icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samnyan/aqua-viewer/a718036ab6baa92d9aa469a9997b3c73e6d9bb1d/src/assets/icons/icon-152x152.png -------------------------------------------------------------------------------- /src/assets/icons/icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samnyan/aqua-viewer/a718036ab6baa92d9aa469a9997b3c73e6d9bb1d/src/assets/icons/icon-192x192.png -------------------------------------------------------------------------------- /src/assets/icons/icon-384x384.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samnyan/aqua-viewer/a718036ab6baa92d9aa469a9997b3c73e6d9bb1d/src/assets/icons/icon-384x384.png -------------------------------------------------------------------------------- /src/assets/icons/icon-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samnyan/aqua-viewer/a718036ab6baa92d9aa469a9997b3c73e6d9bb1d/src/assets/icons/icon-512x512.png -------------------------------------------------------------------------------- /src/assets/icons/icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samnyan/aqua-viewer/a718036ab6baa92d9aa469a9997b3c73e6d9bb1d/src/assets/icons/icon-72x72.png -------------------------------------------------------------------------------- /src/assets/icons/icon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samnyan/aqua-viewer/a718036ab6baa92d9aa469a9997b3c73e6d9bb1d/src/assets/icons/icon-96x96.png -------------------------------------------------------------------------------- /src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true, 3 | assetsHost: '//static.samnyan.icu/' 4 | }; 5 | -------------------------------------------------------------------------------- /src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false, 7 | assetsHost: '//static.samnyan.icu/' 8 | }; 9 | 10 | /* 11 | * For easier debugging in development mode, you can import the following file 12 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 13 | * 14 | * This import should be commented out in production mode because it will have a negative impact 15 | * on performance if an error is thrown. 16 | */ 17 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 18 | -------------------------------------------------------------------------------- /src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samnyan/aqua-viewer/a718036ab6baa92d9aa469a9997b3c73e6d9bb1d/src/favicon.ico -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | AquaViewer 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import {enableProdMode} from '@angular/core'; 2 | import {platformBrowserDynamic} from '@angular/platform-browser-dynamic'; 3 | 4 | import {AppModule} from './app/app.module'; 5 | import {environment} from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.error(err)); 13 | -------------------------------------------------------------------------------- /src/manifest.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aqua-viewer", 3 | "short_name": "aqua-viewer", 4 | "theme_color": "#1976d2", 5 | "background_color": "#fafafa", 6 | "display": "standalone", 7 | "scope": "./", 8 | "start_url": "./", 9 | "icons": [ 10 | { 11 | "src": "assets/icons/icon-72x72.png", 12 | "sizes": "72x72", 13 | "type": "image/png", 14 | "purpose": "maskable any" 15 | }, 16 | { 17 | "src": "assets/icons/icon-96x96.png", 18 | "sizes": "96x96", 19 | "type": "image/png", 20 | "purpose": "maskable any" 21 | }, 22 | { 23 | "src": "assets/icons/icon-128x128.png", 24 | "sizes": "128x128", 25 | "type": "image/png", 26 | "purpose": "maskable any" 27 | }, 28 | { 29 | "src": "assets/icons/icon-144x144.png", 30 | "sizes": "144x144", 31 | "type": "image/png", 32 | "purpose": "maskable any" 33 | }, 34 | { 35 | "src": "assets/icons/icon-152x152.png", 36 | "sizes": "152x152", 37 | "type": "image/png", 38 | "purpose": "maskable any" 39 | }, 40 | { 41 | "src": "assets/icons/icon-192x192.png", 42 | "sizes": "192x192", 43 | "type": "image/png", 44 | "purpose": "maskable any" 45 | }, 46 | { 47 | "src": "assets/icons/icon-384x384.png", 48 | "sizes": "384x384", 49 | "type": "image/png", 50 | "purpose": "maskable any" 51 | }, 52 | { 53 | "src": "assets/icons/icon-512x512.png", 54 | "sizes": "512x512", 55 | "type": "image/png", 56 | "purpose": "maskable any" 57 | } 58 | ] 59 | } 60 | -------------------------------------------------------------------------------- /src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/zone-testing'; 4 | import {getTestBed} from '@angular/core/testing'; 5 | import {BrowserDynamicTestingModule, platformBrowserDynamicTesting} from '@angular/platform-browser-dynamic/testing'; 6 | 7 | declare const require: any; 8 | 9 | // First, initialize the Angular testing environment. 10 | getTestBed().initTestEnvironment( 11 | BrowserDynamicTestingModule, 12 | platformBrowserDynamicTesting() 13 | ); 14 | // Then we find all the tests. 15 | const context = require.context('./', true, /\.spec\.ts$/); 16 | // And load the modules. 17 | context.keys().map(context); 18 | -------------------------------------------------------------------------------- /tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.base.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/app", 5 | "types": [] 6 | }, 7 | "files": [ 8 | "src/main.ts", 9 | "src/polyfills.ts" 10 | ], 11 | "include": [ 12 | "src/**/*.d.ts" 13 | ], 14 | "exclude": [ 15 | "src/test.ts", 16 | "src/**/*.spec.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /tsconfig.base.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "outDir": "./dist/out-tsc", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "downlevelIteration": true, 9 | "experimentalDecorators": true, 10 | "module": "es2020", 11 | "moduleResolution": "node", 12 | "importHelpers": true, 13 | "target": "es2015", 14 | "typeRoots": [ 15 | "node_modules/@types" 16 | ], 17 | "lib": [ 18 | "es2018", 19 | "dom" 20 | ] 21 | }, 22 | "angularCompilerOptions": { 23 | "fullTemplateTypeCheck": true, 24 | "strictInjectionParameters": true 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | /* 2 | This is a "Solution Style" tsconfig.json file, and is used by editors and TypeScript’s language server to improve development experience. 3 | It is not intended to be used to perform a compilation. 4 | 5 | To learn more about this file see: https://angular.io/config/solution-tsconfig. 6 | */ 7 | { 8 | "files": [], 9 | "references": [ 10 | { 11 | "path": "./tsconfig.app.json" 12 | }, 13 | { 14 | "path": "./tsconfig.spec.json" 15 | } 16 | ] 17 | } -------------------------------------------------------------------------------- /tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.base.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/spec", 5 | "types": [ 6 | "jasmine", 7 | "node" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts", 12 | "src/polyfills.ts" 13 | ], 14 | "include": [ 15 | "src/**/*.spec.ts", 16 | "src/**/*.d.ts" 17 | ] 18 | } 19 | --------------------------------------------------------------------------------