├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .postcssrc.js ├── .stylintrc ├── README.md ├── api ├── bestdori │ ├── community │ │ └── [id].js │ └── official │ │ ├── info │ │ └── [id] │ │ │ └── [lang].js │ │ ├── map │ │ └── [id] │ │ │ └── [diff].js │ │ └── music │ │ └── [id].js └── notifications.js ├── babel.config.js ├── crowdin.yml ├── package.json ├── quasar.conf.js ├── src-pwa ├── custom-service-worker.js └── register-service-worker.js ├── src ├── App.vue ├── assets │ └── sad.svg ├── boot │ ├── .gitkeep │ ├── axios.js │ └── i18n.js ├── components │ ├── .gitkeep │ ├── Common │ │ ├── ButtonValue.vue │ │ └── NumberDialog.vue │ ├── Home │ │ ├── About.vue │ │ ├── Convert.vue │ │ ├── Play.vue │ │ └── Space.vue │ └── Public │ │ ├── Favourite.vue │ │ ├── Guide.vue │ │ ├── Notification.vue │ │ ├── SelectLanguage.vue │ │ └── Settings.vue ├── css │ ├── app.styl │ └── quasar.variables.styl ├── i18n │ ├── de_DE │ │ └── index.yaml │ ├── en_US │ │ └── index.yaml │ ├── fr_FR │ │ └── index.yaml │ ├── id_ID │ │ └── index.yaml │ ├── index.js │ ├── ja_JP │ │ └── index.yaml │ ├── ko_KR │ │ └── index.yaml │ ├── ru_RU │ │ └── index.yaml │ ├── zh_CN │ │ └── index.yaml │ └── zh_TW │ │ └── index.yaml ├── index.template.html ├── layouts │ └── Layout.vue ├── lib │ ├── Utils.js │ ├── bbb2bestdori.js │ └── bestdori2bbb.js ├── pages │ ├── Error404.vue │ ├── Index.vue │ └── Play.vue ├── router │ ├── index.js │ └── routes.js ├── statics │ ├── app-logo-128x128.png │ ├── icons │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── favicon-96x96.png │ │ ├── favicon.ico │ │ ├── icon-128x128.png │ │ ├── icon-192x192.png │ │ ├── icon-256x256.png │ │ ├── icon-384x384.png │ │ └── icon-512x512.png │ └── skin │ │ ├── bg.jpg │ │ ├── effect.json │ │ ├── effect.png │ │ ├── flick.mp3 │ │ ├── game.json │ │ ├── game.png │ │ ├── game_button.mp3 │ │ ├── good.mp3 │ │ ├── great.mp3 │ │ ├── long.mp3 │ │ ├── perfect.mp3 │ │ ├── ui.json │ │ └── ui.png └── store │ ├── index.js │ └── module │ ├── actions.js │ ├── getters.js │ ├── index.js │ ├── mutations.js │ └── state.js └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = tab 6 | indent_size = 4 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | /dist 2 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | 4 | parserOptions: { 5 | parser: 'babel-eslint', 6 | sourceType: 'module' 7 | }, 8 | 9 | env: { 10 | browser: true 11 | }, 12 | 13 | extends: [ 14 | // https://eslint.vuejs.org/rules/#priority-a-essential-error-prevention 15 | // consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules. 16 | 'plugin:vue/essential', 17 | '@vue/standard' 18 | ], 19 | 20 | // required to lint *.vue files 21 | plugins: [ 22 | 'vue' 23 | ], 24 | 25 | globals: { 26 | 'ga': true, // Google Analytics 27 | 'cordova': true, 28 | '__statics': true, 29 | 'process': true, 30 | 'Capacitor': true, 31 | 'chrome': true 32 | }, 33 | 34 | // add your custom rules here 35 | rules: { 36 | // allow async-await 37 | 'generator-star-spacing': 'off', 38 | // allow paren-less arrow functions 39 | 'arrow-parens': 'off', 40 | 'one-var': 'off', 41 | 'no-tabs': 'off', 42 | 'indent': 'off', 43 | 'no-mixed-spaces-and-tabs': 'off', 44 | 'vue/script-indent': ['error', 'tab', { 45 | 'baseIndent': 1, 46 | 'switchCase': 1 47 | }], 48 | 'semi': ['error', 'always'], 49 | 50 | 'import/first': 'off', 51 | 'import/named': 'error', 52 | 'import/namespace': 'error', 53 | 'import/default': 'error', 54 | 'import/export': 'error', 55 | 'import/extensions': 'off', 56 | 'import/no-unresolved': 'off', 57 | 'import/no-extraneous-dependencies': 'off', 58 | 'prefer-promise-reject-errors': 'off', 59 | 60 | // allow debugger during development only 61 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off' 62 | } 63 | }; 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .thumbs.db 3 | node_modules 4 | 5 | # Quasar core related directories 6 | .quasar 7 | /dist 8 | 9 | # Cordova related directories and files 10 | /src-cordova/node_modules 11 | /src-cordova/platforms 12 | /src-cordova/plugins 13 | /src-cordova/www 14 | 15 | # Capacitor related directories and files 16 | /src-capacitor/www 17 | /src-capacitor/node_modules 18 | 19 | # BEX related directories and files 20 | /src-bex/www 21 | /src-bex/js/core 22 | 23 | # Log files 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # Editor directories and files 29 | .idea 30 | .vscode 31 | *.suo 32 | *.ntvs* 33 | *.njsproj 34 | *.sln 35 | 36 | .now -------------------------------------------------------------------------------- /.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | plugins: [ 5 | // to edit target browsers: use "browserslist" field in package.json 6 | require('autoprefixer') 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /.stylintrc: -------------------------------------------------------------------------------- 1 | { 2 | "blocks": "never", 3 | "brackets": "never", 4 | "colons": "never", 5 | "colors": "always", 6 | "commaSpace": "always", 7 | "commentSpace": "always", 8 | "cssLiteral": "never", 9 | "depthLimit": false, 10 | "duplicates": true, 11 | "efficient": "always", 12 | "extendPref": false, 13 | "globalDupe": true, 14 | "indentPref": 2, 15 | "leadingZero": "never", 16 | "maxErrors": false, 17 | "maxWarnings": false, 18 | "mixed": false, 19 | "namingConvention": false, 20 | "namingConventionStrict": false, 21 | "none": "never", 22 | "noImportant": false, 23 | "parenSpace": "never", 24 | "placeholder": false, 25 | "prefixVarsWithDollar": "always", 26 | "quotePref": "single", 27 | "semicolons": "never", 28 | "sortOrder": false, 29 | "stackedProperties": "never", 30 | "trailingWhitespace": "never", 31 | "universal": "never", 32 | "valid": true, 33 | "zeroUnits": "never", 34 | "zIndexNormalize": false 35 | } 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Quasar App (banground-player) 2 | 3 | banground map player 4 | 5 | ## Install the dependencies 6 | ```bash 7 | yarn 8 | ``` 9 | 10 | ### Start the app in development mode (hot-code reloading, error reporting, etc.) 11 | ```bash 12 | quasar dev 13 | ``` 14 | 15 | ### Lint the files 16 | ```bash 17 | yarn run lint 18 | ``` 19 | 20 | ### Build the app for production 21 | ```bash 22 | quasar build 23 | ``` 24 | 25 | ### Customize the configuration 26 | See [Configuring quasar.conf.js](https://quasar.dev/quasar-cli/quasar-conf-js). 27 | -------------------------------------------------------------------------------- /api/bestdori/community/[id].js: -------------------------------------------------------------------------------- 1 | const axios = require('axios'); 2 | 3 | module.exports = async (req, res) => { 4 | const { id } = req.query; 5 | try { 6 | let { data } = await axios(`https://bestdori.com/api/post/details?id=${id}`); 7 | if (!data.result || data.post.categoryId !== 'chart') { 8 | throw new Error(); 9 | } 10 | let { post } = data; 11 | res.json({ 12 | result: true, 13 | data: { 14 | name: post.title, 15 | music: post.song, 16 | artists: post.artists, 17 | difficulty: post.diff, 18 | level: post.level, 19 | author: { 20 | username: post.author.username, 21 | nickname: post.author.nickname 22 | }, 23 | notes: post.notes 24 | } 25 | }); 26 | } catch (e) { 27 | res.json({ result: false }); 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /api/bestdori/official/info/[id]/[lang].js: -------------------------------------------------------------------------------- 1 | const axios = require('axios'); 2 | const _ = require('lodash'); 3 | 4 | module.exports = async (req, res) => { 5 | const { id, lang } = req.query; 6 | const langId = ({ 7 | ja: 0, 8 | en: 1, 9 | zh: 3 10 | })[lang]; 11 | try { 12 | let { data } = await axios(`https://bestdori.com/api/songs/${id}.json`); 13 | let { data: band } = await axios('https://bestdori.com/api/bands/all.1.json'); 14 | res.json({ 15 | result: true, 16 | data: { 17 | name: data.musicTitle[langId] || data.musicTitle[0], 18 | band: band[data.bandId].bandName[langId] || band[data.bandId].bandName[0], 19 | difficulty: _.mapValues(data.difficulty, (v, k) => { 20 | return { 21 | level: v.playLevel, 22 | notes: data.notes[k] 23 | }; 24 | }) 25 | } 26 | }); 27 | } catch (e) { 28 | res.json({ result: false }); 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /api/bestdori/official/map/[id]/[diff].js: -------------------------------------------------------------------------------- 1 | const axios = require('axios'); 2 | 3 | module.exports = async (req, res) => { 4 | const { id, diff } = req.query; 5 | try { 6 | let { data } = await axios.get(`https://bestdori.com/api/songs/chart/${id}.${diff}.json`); 7 | res.json({ 8 | result: true, 9 | data 10 | }); 11 | } catch (e) { 12 | res.json({ result: false }); 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /api/bestdori/official/music/[id].js: -------------------------------------------------------------------------------- 1 | const axios = require('axios'); 2 | 3 | module.exports = async (req, res) => { 4 | const { id } = req.query; 5 | try { 6 | let { data } = await axios.get('https://bestdori.com/api/songs/all.player.json'); 7 | if (!data[id]) { 8 | throw new Error(); 9 | } 10 | let bgm = data[id].bgmId; 11 | res.json({ 12 | result: true, 13 | data: `https://bestdori.com/assets/jp/sound/${bgm}_rip/${bgm}.mp3` 14 | }); 15 | } catch (e) { 16 | res.json({ result: false }); 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /api/notifications.js: -------------------------------------------------------------------------------- 1 | const axios = require('axios'); 2 | 3 | module.exports = async (req, res) => { 4 | try { 5 | let { data } = await axios('https://gist.githubusercontent.com/zz5840/b0821d70f51b93bb7bf7f5db5267f130/raw'); 6 | res.json(data); 7 | } catch (e) { 8 | res.json({ result: false, error: e }); 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@quasar/babel-preset-app' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /crowdin.yml: -------------------------------------------------------------------------------- 1 | files: 2 | - source: /src/i18n/en_US/index.yaml 3 | translation: /src/i18n/%locale_with_underscore%/index.yaml 4 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "banground-player", 3 | "version": "0.0.1", 4 | "description": "banground map player", 5 | "productName": "BanGround Player", 6 | "author": "zz5840 ", 7 | "private": true, 8 | "scripts": { 9 | "lint": "eslint --ext .js,.vue src", 10 | "test": "echo \"No test specified\" && exit 0" 11 | }, 12 | "dependencies": { 13 | "@quasar/extras": "^1.5.0", 14 | "axios": "^0.19.2", 15 | "bangbangboom-game": "https://github.com/K024/bangbangboom-game.git", 16 | "file-saver": "^2.0.2", 17 | "json-loader": "^0.5.7", 18 | "lodash": "^4.17.15", 19 | "quasar": "^1.8.3", 20 | "screenfull": "^5.0.1", 21 | "showdown": "^1.9.1", 22 | "vue-i18n": "^8.0.0", 23 | "vuex-persistedstate": "^2.7.1", 24 | "yaml-loader": "^0.5.0" 25 | }, 26 | "devDependencies": { 27 | "@quasar/app": "^1.0.0", 28 | "@vue/eslint-config-standard": "^4.0.0", 29 | "babel-eslint": "^10.0.1", 30 | "eslint": "^5.10.0", 31 | "eslint-loader": "^2.1.1", 32 | "eslint-plugin-vue": "^5.0.0" 33 | }, 34 | "engines": { 35 | "node": ">= 10.18.1", 36 | "npm": ">= 6.13.4", 37 | "yarn": ">= 1.21.1" 38 | }, 39 | "browserslist": [ 40 | "last 1 version, not dead, ie >= 11" 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /quasar.conf.js: -------------------------------------------------------------------------------- 1 | // Configuration for your app 2 | // https://quasar.dev/quasar-cli/quasar-conf-js 3 | 4 | module.exports = function (ctx) { 5 | return { 6 | // app boot file (/src/boot) 7 | // --> boot files are part of "main.js" 8 | // https://quasar.dev/quasar-cli/cli-documentation/boot-files 9 | boot: [ 10 | 'i18n', 11 | 'axios' 12 | ], 13 | 14 | // https://quasar.dev/quasar-cli/quasar-conf-js#Property%3A-css 15 | css: [ 16 | 'app.styl' 17 | ], 18 | 19 | // https://github.com/quasarframework/quasar/tree/dev/extras 20 | extras: [ 21 | // 'ionicons-v4', 22 | // 'fontawesome-v5', 23 | // 'eva-icons', 24 | // 'themify', 25 | // 'roboto-font-latin-ext', // this or either 'roboto-font', NEVER both! 26 | 27 | 'mdi-v4', 28 | 'roboto-font' 29 | ], 30 | 31 | // https://quasar.dev/quasar-cli/quasar-conf-js#Property%3A-framework 32 | framework: { 33 | iconSet: 'mdi-v4', // Quasar icon set 34 | lang: 'en-us', // Quasar language pack 35 | 36 | // Possible values for "all": 37 | // * 'auto' - Auto-import needed Quasar components & directives 38 | // (slightly higher compile time; next to minimum bundle size; most convenient) 39 | // * false - Manually specify what to import 40 | // (fastest compile time; minimum bundle size; most tedious) 41 | // * true - Import everything from Quasar 42 | // (not treeshaking Quasar; biggest bundle size; convenient) 43 | all: 'auto', 44 | 45 | components: [ 46 | 'QBtn', 47 | 'QBtnGroup', 48 | 'QTabs', 49 | 'QTab', 50 | 'QRouteTab', 51 | 'QRadio', 52 | 'QField', 53 | 'QDialog', 54 | 'QList', 55 | 'QItem', 56 | 'QItemSection', 57 | 'QItemLabel', 58 | 'QFile', 59 | 'QMarkupTable', 60 | 'QSpinnerFacebook' 61 | ], 62 | directives: [ 63 | 'Ripple' 64 | ], 65 | 66 | // Quasar plugins 67 | plugins: [ 68 | 'Dialog', 69 | 'Notify', 70 | 'LocalStorage' 71 | ] 72 | }, 73 | 74 | // https://quasar.dev/quasar-cli/cli-documentation/supporting-ie 75 | supportIE: false, 76 | // Full list of options: https://quasar.dev/quasar-cli/quasar-conf-js#Property%3A-build 77 | build: { 78 | distDir: ctx.mode.spa ? 'public' : null, 79 | scopeHoisting: true, 80 | vueRouterMode: 'history', // available values: 'hash', 'history' 81 | showProgress: true, 82 | gzip: false, 83 | analyze: false, 84 | // Options below are automatically set depending on the env, set them if you want to override 85 | // preloadChunks: false, 86 | // extractCSS: false, 87 | 88 | // https://quasar.dev/quasar-cli/cli-documentation/handling-webpack 89 | extendWebpack (cfg) { 90 | cfg.module.rules.push({ 91 | enforce: 'pre', 92 | test: /\.(js|vue)$/, 93 | loader: 'eslint-loader', 94 | exclude: /node_modules/, 95 | options: { 96 | formatter: require('eslint').CLIEngine.getFormatter('stylish') 97 | } 98 | }, { 99 | test: /\.yaml$/, 100 | use: ['json-loader', 'yaml-loader'] 101 | }); 102 | } 103 | }, 104 | 105 | // Full list of options: https://quasar.dev/quasar-cli/quasar-conf-js#Property%3A-devServer 106 | devServer: { 107 | https: false, 108 | port: 8080, 109 | proxy: { 110 | '/api': { 111 | target: 'https://player.banground.fun/', 112 | secure: true, 113 | changeOrigin: true 114 | } 115 | }, 116 | open: true // opens browser window automatically 117 | }, 118 | 119 | // animations: 'all', // --- includes all animations 120 | // https://quasar.dev/options/animations 121 | animations: [], 122 | 123 | // https://quasar.dev/quasar-cli/developing-ssr/configuring-ssr 124 | ssr: { 125 | pwa: false 126 | }, 127 | 128 | // https://quasar.dev/quasar-cli/developing-pwa/configuring-pwa 129 | pwa: { 130 | workboxPluginMode: 'GenerateSW', // 'GenerateSW' or 'InjectManifest' 131 | workboxOptions: {}, // only for GenerateSW 132 | manifest: { 133 | name: 'BanGround Player', 134 | short_name: 'BG Player', 135 | description: 'BanGround Map Player', 136 | display: 'fullscreen', 137 | orientation: 'landscape', 138 | background_color: '#ffffff', 139 | theme_color: '#2DAAE4', 140 | icons: [ 141 | { 142 | 'src': 'statics/icons/icon-128x128.png', 143 | 'sizes': '128x128', 144 | 'type': 'image/png' 145 | }, 146 | { 147 | 'src': 'statics/icons/icon-192x192.png', 148 | 'sizes': '192x192', 149 | 'type': 'image/png' 150 | }, 151 | { 152 | 'src': 'statics/icons/icon-256x256.png', 153 | 'sizes': '256x256', 154 | 'type': 'image/png' 155 | }, 156 | { 157 | 'src': 'statics/icons/icon-384x384.png', 158 | 'sizes': '384x384', 159 | 'type': 'image/png' 160 | }, 161 | { 162 | 'src': 'statics/icons/icon-512x512.png', 163 | 'sizes': '512x512', 164 | 'type': 'image/png' 165 | } 166 | ] 167 | } 168 | }, 169 | 170 | // Full list of options: https://quasar.dev/quasar-cli/developing-cordova-apps/configuring-cordova 171 | cordova: { 172 | // noIosLegacyBuildFlag: true, // uncomment only if you know what you are doing 173 | id: 'org.cordova.quasar.app' 174 | }, 175 | 176 | // Full list of options: https://quasar.dev/quasar-cli/developing-capacitor-apps/configuring-capacitor 177 | capacitor: { 178 | hideSplashscreen: true 179 | }, 180 | 181 | // Full list of options: https://quasar.dev/quasar-cli/developing-electron-apps/configuring-electron 182 | electron: { 183 | bundler: 'packager', // 'packager' or 'builder' 184 | 185 | packager: { 186 | // https://github.com/electron-userland/electron-packager/blob/master/docs/api.md#options 187 | 188 | // OS X / Mac App Store 189 | // appBundleId: '', 190 | // appCategoryType: '', 191 | // osxSign: '', 192 | // protocol: 'myapp://path', 193 | 194 | // Windows only 195 | // win32metadata: { ... } 196 | }, 197 | 198 | builder: { 199 | // https://www.electron.build/configuration/configuration 200 | 201 | appId: 'banground-player' 202 | }, 203 | 204 | // More info: https://quasar.dev/quasar-cli/developing-electron-apps/node-integration 205 | nodeIntegration: true, 206 | 207 | extendWebpack (cfg) { 208 | // do something with Electron main process Webpack cfg 209 | // chainWebpack also available besides this extendWebpack 210 | } 211 | } 212 | }; 213 | }; 214 | -------------------------------------------------------------------------------- /src-pwa/custom-service-worker.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This file (which will be your service worker) 3 | * is picked up by the build system ONLY if 4 | * quasar.conf > pwa > workboxPluginMode is set to "InjectManifest" 5 | */ 6 | -------------------------------------------------------------------------------- /src-pwa/register-service-worker.js: -------------------------------------------------------------------------------- 1 | import { register } from 'register-service-worker' 2 | 3 | // The ready(), registered(), cached(), updatefound() and updated() 4 | // events passes a ServiceWorkerRegistration instance in their arguments. 5 | // ServiceWorkerRegistration: https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration 6 | 7 | register(process.env.SERVICE_WORKER_FILE, { 8 | // The registrationOptions object will be passed as the second argument 9 | // to ServiceWorkerContainer.register() 10 | // https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/register#Parameter 11 | 12 | // registrationOptions: { scope: './' }, 13 | 14 | ready () { 15 | if (process.env.DEV) { 16 | console.log('App is being served from cache by a service worker.') 17 | } 18 | }, 19 | 20 | registered (/* registration */) { 21 | if (process.env.DEV) { 22 | console.log('Service worker has been registered.') 23 | } 24 | }, 25 | 26 | cached (/* registration */) { 27 | if (process.env.DEV) { 28 | console.log('Content has been cached for offline use.') 29 | } 30 | }, 31 | 32 | updatefound (/* registration */) { 33 | if (process.env.DEV) { 34 | console.log('New content is downloading.') 35 | } 36 | }, 37 | 38 | updated (/* registration */) { 39 | if (process.env.DEV) { 40 | console.log('New content is available; please refresh.') 41 | } 42 | }, 43 | 44 | offline () { 45 | if (process.env.DEV) { 46 | console.log('No internet connection found. App is running in offline mode.') 47 | } 48 | }, 49 | 50 | error (err) { 51 | if (process.env.DEV) { 52 | console.error('Error during service worker registration:', err) 53 | } 54 | } 55 | }) 56 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /src/assets/sad.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/boot/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zz5840/BanGround-Player/1e713220a990a73baf0199440e04915828b382e2/src/boot/.gitkeep -------------------------------------------------------------------------------- /src/boot/axios.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import axios from 'axios'; 3 | 4 | Vue.prototype.$a = axios; 5 | -------------------------------------------------------------------------------- /src/boot/i18n.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import VueI18n from 'vue-i18n'; 3 | import messages from 'src/i18n'; 4 | 5 | Vue.use(VueI18n); 6 | 7 | const i18n = new VueI18n({ 8 | locale: 'en', 9 | fallbackLocale: 'zh', 10 | messages 11 | }); 12 | 13 | export default ({ app }) => { 14 | // Set i18n instance on app 15 | app.i18n = i18n; 16 | }; 17 | 18 | export { i18n }; 19 | -------------------------------------------------------------------------------- /src/components/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zz5840/BanGround-Player/1e713220a990a73baf0199440e04915828b382e2/src/components/.gitkeep -------------------------------------------------------------------------------- /src/components/Common/ButtonValue.vue: -------------------------------------------------------------------------------- 1 | 27 | 28 | 81 | 82 | 85 | -------------------------------------------------------------------------------- /src/components/Common/NumberDialog.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 57 | 60 | -------------------------------------------------------------------------------- /src/components/Home/About.vue: -------------------------------------------------------------------------------- 1 | 28 | 29 | 34 | 35 | 38 | -------------------------------------------------------------------------------- /src/components/Home/Convert.vue: -------------------------------------------------------------------------------- 1 |