mirror of
https://gitlab.com/deeplydrumming/DeemixFix.git
synced 2026-01-15 16:32:59 -03:00
update to vue 2.7 and fix spotify
This commit is contained in:
@@ -20,7 +20,6 @@
|
||||
"@rollup/plugin-commonjs": "20.0.0",
|
||||
"@rollup/plugin-node-resolve": "13.3.0",
|
||||
"@rollup/plugin-replace": "3.1.0",
|
||||
"@vue/composition-api": "1.7.2",
|
||||
"esbuild": "0.23.1",
|
||||
"flag-icon-css": "4.1.7",
|
||||
"lodash-es": "4.17.21",
|
||||
@@ -34,7 +33,10 @@
|
||||
"tailwindcss": "1.9.6",
|
||||
"toastify-js": "1.12.0",
|
||||
"vue": "2.7.16",
|
||||
"vue-i18n": "8.28.2",
|
||||
"vue-demi": "^0.14.10",
|
||||
"vue-i18n": "8.26.1",
|
||||
"vue-i18n-bridge": "^9.14.0",
|
||||
"vue-loader": "^17.4.2",
|
||||
"vue-router": "3.6.5",
|
||||
"vuex": "3.6.2"
|
||||
},
|
||||
@@ -47,7 +49,6 @@
|
||||
"jest": "27.5.1",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"rimraf": "3.0.2",
|
||||
"typescript": "4.9.5",
|
||||
"vue-template-compiler": "2.7.16"
|
||||
"typescript": "4.9.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import Vue from 'vue'
|
||||
|
||||
import '@/plugins/composition-api'
|
||||
|
||||
import '@/styles/vendor/material-icons.css'
|
||||
import '@/styles/vendor/OpenSans.css'
|
||||
|
||||
@@ -39,12 +37,13 @@ if (location.base == '<%= locationBase %>') location.base = '/'
|
||||
/* ===== App initialization ===== */
|
||||
async function startApp () {
|
||||
document.getElementById('missingBundle').remove()
|
||||
new Vue({
|
||||
store,
|
||||
router,
|
||||
i18n,
|
||||
render: h => h(App)
|
||||
}).$mount('#app')
|
||||
const app = new Vue({
|
||||
store,
|
||||
router,
|
||||
i18n,
|
||||
render: h => h(App)
|
||||
})
|
||||
app.$mount('#app')
|
||||
|
||||
const connectResponse = await fetchData('connect')
|
||||
const spotifyStatus = connectResponse.spotifyEnabled ? SPOTIFY_STATUS.ENABLED : SPOTIFY_STATUS.DISABLED
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import { defineComponent, ref } from '@vue/composition-api'
|
||||
import { defineComponent, ref } from 'vue'
|
||||
import { isValidURL } from '@/utils/utils'
|
||||
import { sendAddToQueue } from '@/utils/downloads'
|
||||
import { fetchData } from '@/utils/api'
|
||||
|
||||
@@ -35,26 +35,33 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { computed, defineComponent, reactive, toRefs } from '@vue/composition-api'
|
||||
import { computed, defineComponent, reactive, toRefs } from 'vue'
|
||||
import { links } from '@/data/sidebar'
|
||||
import { mapGetters } from 'vuex'
|
||||
import { useTheme } from '@/use/theme'
|
||||
import deemixIcon from '@/assets/deemix-icon.svg'
|
||||
import { useRouter, useRoute } from '@/router'
|
||||
import { useStore } from '@/store'
|
||||
|
||||
export default defineComponent({
|
||||
setup(_, ctx) {
|
||||
const activeTab = links.find(link => link.routerName === ctx.root.$route.name)
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const store = useStore()
|
||||
|
||||
const activeTab = links.find(link => link.routerName === route.name)
|
||||
|
||||
const state = reactive({
|
||||
activeTablink: activeTab ? activeTab.name : 'home',
|
||||
links
|
||||
})
|
||||
|
||||
const { THEMES, currentTheme } = useTheme()
|
||||
|
||||
/* === Add update notification near info === */
|
||||
const updateAvailable = computed(() => ctx.root.$store.state.appInfo.updateAvailable)
|
||||
const updateAvailable = computed(() => store.state.appInfo.updateAvailable)
|
||||
|
||||
ctx.root.$router.afterEach(to => {
|
||||
router.afterEach(to => {
|
||||
const linkInSidebar = state.links.find(link => link.routerName === to.name)
|
||||
|
||||
if (!linkInSidebar) return
|
||||
@@ -66,7 +73,7 @@ export default defineComponent({
|
||||
...toRefs(state),
|
||||
currentTheme,
|
||||
deemixIcon,
|
||||
isSlim: computed(() => ctx.root.$store.getters.getSlimSidebar),
|
||||
isSlim: computed(() => store.getters.getSlimSidebar),
|
||||
THEMES,
|
||||
updateAvailable,
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* eslint-disable vue/one-component-per-file */
|
||||
import { defineComponent } from '@vue/composition-api'
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
// https://vuejs.org/v2/guide/render-function.html
|
||||
// https://vuejs.org/v2/guide/render-function.html#createElement-Arguments
|
||||
|
||||
@@ -207,16 +207,18 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { computed, defineComponent, onMounted, reactive, toRefs } from '@vue/composition-api'
|
||||
import { computed, defineComponent, onMounted, reactive, toRefs } from 'vue'
|
||||
import BaseAccordion from '@/components/globals/BaseAccordion.vue';
|
||||
|
||||
import { useOnline } from '@/use/online'
|
||||
import { useStore } from '@/store';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
BaseAccordion
|
||||
},
|
||||
setup(_, ctx) {
|
||||
const store = useStore();
|
||||
const state = reactive({
|
||||
current: null,
|
||||
latest: null,
|
||||
@@ -234,7 +236,7 @@ export default defineComponent({
|
||||
state.deemixVersion = deemixVersion
|
||||
}
|
||||
|
||||
const getAppInfo = computed(() => ctx.root.$store.getters.getAppInfo)
|
||||
const getAppInfo = computed(() => store.getters.getAppInfo)
|
||||
|
||||
onMounted(() => {
|
||||
initUpdate(getAppInfo.value)
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent, ref, unref, reactive, computed, toRefs } from '@vue/composition-api'
|
||||
import { defineComponent, ref, unref, reactive, computed, toRefs } from 'vue'
|
||||
import { orderBy } from 'lodash-es'
|
||||
|
||||
import { BaseTabs, BaseTab } from '@/components/globals/BaseTabs'
|
||||
@@ -109,6 +109,7 @@ import { sendAddToQueue } from '@/utils/downloads'
|
||||
import { checkNewRelease } from '@/utils/dates'
|
||||
import { formatArtistData, getArtistData } from '@/data/artist'
|
||||
import { standardizeData } from '@/data/standardize'
|
||||
import { useRouter } from '@/router'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
@@ -116,6 +117,7 @@ export default defineComponent({
|
||||
BaseTab
|
||||
},
|
||||
setup(_, ctx) {
|
||||
const router = useRouter()
|
||||
const state = reactive({
|
||||
currentTab: '',
|
||||
sortKey: 'releaseDate',
|
||||
@@ -126,7 +128,7 @@ export default defineComponent({
|
||||
currentRelease: computed(() => state.artistReleases[state.currentTab])
|
||||
})
|
||||
|
||||
const artistID = computed(() => ctx.root.$router.currentRoute.params.id)
|
||||
const artistID = computed(() => router.currentRoute.params.id)
|
||||
const hasDataLoaded = ref(false)
|
||||
|
||||
getArtistData(unref(artistID))
|
||||
|
||||
@@ -134,13 +134,14 @@
|
||||
import { aggregateDownloadLinks, sendAddToQueue } from '@/utils/downloads'
|
||||
import { BaseTab, BaseTabs } from '@/components/globals/BaseTabs'
|
||||
import { convertDuration } from '@/utils/utils'
|
||||
import { defineComponent, reactive, toRefs, watch } from '@vue/composition-api'
|
||||
import { defineComponent, reactive, toRefs, watch } from 'vue'
|
||||
import { playPausePreview } from '@/components/globals/TheTrackPreview.vue'
|
||||
import { toast } from '@/utils/toasts'
|
||||
import { useFavorites } from '@/use/favorites'
|
||||
import BaseLoadingPlaceholder from '@/components/globals/BaseLoadingPlaceholder.vue'
|
||||
import CoverContainer from '@/components/globals/CoverContainer.vue'
|
||||
import PreviewControls from '@/components/globals/PreviewControls.vue'
|
||||
import { useI18n } from 'vue-i18n-bridge';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
@@ -155,6 +156,7 @@ export default defineComponent({
|
||||
activeTab: 'playlist',
|
||||
tabs: ['playlist', 'album', 'artist', 'track']
|
||||
})
|
||||
const i18n = useI18n()
|
||||
const {
|
||||
favoriteArtists,
|
||||
favoriteAlbums,
|
||||
@@ -174,7 +176,7 @@ export default defineComponent({
|
||||
|
||||
if (!isRefreshingTerminated) return
|
||||
|
||||
toast(ctx.root.$t('toasts.refreshFavs'), 'done', true)
|
||||
toast(i18n.t('toasts.refreshFavs'), 'done', true)
|
||||
})
|
||||
|
||||
return {
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { computed, onMounted, reactive, ref, toRefs, watch, defineComponent } from '@vue/composition-api'
|
||||
import { computed, onMounted, reactive, ref, toRefs, watch, defineComponent } from 'vue'
|
||||
import { uniqWith } from 'lodash-es'
|
||||
|
||||
import BaseLoadingPlaceholder from '@/components/globals/BaseLoadingPlaceholder.vue'
|
||||
@@ -51,6 +51,8 @@ import { formatSingleTrack, formatAlbums, formatArtist, formatPlaylist } from '@
|
||||
import { standardizeData } from '@/data/standardize'
|
||||
import { useMainSearch } from '@/use/main-search'
|
||||
import { useSearch } from '@/use/search'
|
||||
import { useI18n } from 'vue-i18n-bridge'
|
||||
import { useRoute } from '@/router'
|
||||
|
||||
const resetObj = { data: [], next: 0, total: 0, hasLoaded: false }
|
||||
|
||||
@@ -69,6 +71,7 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
setup(_, ctx) {
|
||||
const i18n = useI18n()
|
||||
const state = reactive({
|
||||
currentTab: {
|
||||
name: '',
|
||||
@@ -102,34 +105,34 @@ export default defineComponent({
|
||||
},
|
||||
tabs: [
|
||||
{
|
||||
name: ctx.root.$i18n.t('globals.listTabs.all'),
|
||||
name: i18n.t('globals.listTabs.all'),
|
||||
searchType: 'all',
|
||||
component: ResultsAll,
|
||||
viewInfo: 'allTab'
|
||||
},
|
||||
{
|
||||
name: ctx.root.$i18n.tc('globals.listTabs.track', 2),
|
||||
name: i18n.t('globals.listTabs.track', 2),
|
||||
searchType: 'track',
|
||||
component: ResultsTracks,
|
||||
viewInfo: 'trackTab',
|
||||
formatFunc: formatSingleTrack
|
||||
},
|
||||
{
|
||||
name: ctx.root.$i18n.tc('globals.listTabs.album', 2),
|
||||
name: i18n.t('globals.listTabs.album', 2),
|
||||
searchType: 'album',
|
||||
component: ResultsAlbums,
|
||||
viewInfo: 'albumTab',
|
||||
formatFunc: formatAlbums
|
||||
},
|
||||
{
|
||||
name: ctx.root.$i18n.tc('globals.listTabs.artist', 2),
|
||||
name: i18n.t('globals.listTabs.artist', 2),
|
||||
searchType: 'artist',
|
||||
component: ResultsArtists,
|
||||
viewInfo: 'artistTab',
|
||||
formatFunc: formatArtist
|
||||
},
|
||||
{
|
||||
name: ctx.root.$i18n.tc('globals.listTabs.playlist', 2),
|
||||
name: i18n.t('globals.listTabs.playlist', 2),
|
||||
searchType: 'playlist',
|
||||
component: ResultsPlaylists,
|
||||
viewInfo: 'playlistTab',
|
||||
@@ -137,10 +140,11 @@ export default defineComponent({
|
||||
}
|
||||
]
|
||||
})
|
||||
const route = useRoute()
|
||||
const { searchResult, performMainSearch } = useMainSearch()
|
||||
const { result, performSearch } = useSearch()
|
||||
const cachedSearchedTerm = computed(() => searchResult.value.QUERY)
|
||||
const searchedTerm = computed(() => ctx.root.$route.query.term || cachedSearchedTerm.value)
|
||||
const searchedTerm = computed(() => route.query.term || cachedSearchedTerm.value)
|
||||
const isQueryEmpty = computed(() => state.results.query === '')
|
||||
const isSearching = ref(false)
|
||||
const isMainSearchCached = computed(() => Object.keys(searchResult.value).length !== 0)
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
</div>
|
||||
|
||||
<div class="relative">
|
||||
<BaseLoadingPlaceholder v-if="isRefreshingSpotifyPlaylists" :text="$t('globals.loading')" additional-classes="absolute top-0 left-0 w-full" />
|
||||
<BaseLoadingPlaceholder v-if="isRefreshingSpotifyPlaylists" :text="$t('globals.loading')" additional-classes="absolute top-10 left-0 w-full" />
|
||||
<div v-else>
|
||||
<h2 class="mb-6 text-3xl">{{ $t('spotifyHome.subHeading') }}</h2>
|
||||
<BaseAccordion class="warning">
|
||||
@@ -60,10 +60,11 @@ import CoverContainer from '@/components/globals/CoverContainer.vue';
|
||||
import PreviewControls from '@/components/globals/PreviewControls.vue';
|
||||
|
||||
import { useSpotifyPlaylists } from '@/use/spotifyplaylists';
|
||||
import { ref, watch } from '@vue/composition-api';
|
||||
import { ref, watch } from 'vue';
|
||||
import { toast } from '@/utils/toasts';
|
||||
import { socket } from '@/utils/socket';
|
||||
import store from '@/store';
|
||||
import { useI18n } from 'vue-i18n-bridge';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -74,10 +75,11 @@ export default {
|
||||
CoverContainer,
|
||||
PreviewControls,
|
||||
},
|
||||
setup(_, { root }) {
|
||||
setup() {
|
||||
const lastUser = ref('');
|
||||
const spotifyUser = ref('');
|
||||
|
||||
const i18n = useI18n();
|
||||
const {
|
||||
favoriteSpotifyPlaylists,
|
||||
isRefreshingSpotifyPlaylists,
|
||||
@@ -96,7 +98,7 @@ export default {
|
||||
watch(isRefreshingSpotifyPlaylists, (newVal, oldVal) => {
|
||||
const isRefreshingTerminated = oldVal && !newVal;
|
||||
if (!isRefreshingTerminated) return;
|
||||
toast(root.$t('toasts.refreshFavs'), 'done', true);
|
||||
toast(i18n.t('toasts.refreshFavs'), 'done', true);
|
||||
});
|
||||
|
||||
refreshSpotifyPlaylists().catch(console.error);
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
import Vue from 'vue'
|
||||
import VueCompositionAPI from '@vue/composition-api'
|
||||
|
||||
Vue.use(VueCompositionAPI)
|
||||
@@ -1,19 +1,28 @@
|
||||
import Vue from 'vue'
|
||||
import VueI18n from 'vue-i18n'
|
||||
import { createI18n } from 'vue-i18n-bridge'
|
||||
|
||||
import { locales } from '@/lang'
|
||||
|
||||
Vue.use(VueI18n)
|
||||
Vue.use(VueI18n, { bridge: true })
|
||||
|
||||
const storedLocale = window.localStorage.getItem('locale')
|
||||
const DEFAULT_LANG = storedLocale || 'en'
|
||||
|
||||
document.querySelector('html').setAttribute('lang', DEFAULT_LANG)
|
||||
|
||||
const i18n = new VueI18n({
|
||||
const i18n = createI18n({
|
||||
locale: DEFAULT_LANG,
|
||||
legacy: false,
|
||||
fallbackLocale: 'en',
|
||||
messages: locales,
|
||||
// since this is a vue 2 app using the latest vue i18n with the vue-i18n-bridge,
|
||||
// there will be some warnings
|
||||
// the update from vue 2.6 to vue 2.7 required me to use vue-i18n-bridge anywa,
|
||||
// might as well use the latest vue-i18n
|
||||
warnHtmlMessage: false,
|
||||
warnHtmlInMessage: false,
|
||||
silentFallbackWarn: true,
|
||||
pluralizationRules: {
|
||||
/**
|
||||
* @param {number} choice A choice index given by the input to $tc: `$tc('path.to.rule', choiceIndex)`
|
||||
@@ -39,6 +48,8 @@ const i18n = new VueI18n({
|
||||
return 2
|
||||
}
|
||||
}
|
||||
})
|
||||
}, VueI18n)
|
||||
|
||||
Vue.use(i18n)
|
||||
|
||||
export default i18n
|
||||
|
||||
@@ -133,6 +133,8 @@ const router = new VueRouter({
|
||||
}
|
||||
})
|
||||
|
||||
import { computed, reactive, getCurrentInstance } from 'vue'
|
||||
|
||||
router.beforeEach((to, _, next) => {
|
||||
switch (to.name) {
|
||||
case 'Tracklist': {
|
||||
@@ -181,4 +183,42 @@ router.beforeEach((to, _, next) => {
|
||||
next()
|
||||
})
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {Object} RouteObject
|
||||
* @property {string} fullPath - The full resolved path, including query and hash.
|
||||
* @property {string} hash - The URL hash, if any, starting with `#`.
|
||||
* @property {Array<any>} matched - Array of route records that were matched.
|
||||
* @property {Record<string, any>} meta - Custom route metadata.
|
||||
* @property {string | null} name - The name of the route (if named), or `null`.
|
||||
* @property {Record<string, any>} params - Key-value pairs of dynamic segments and their values.
|
||||
* @property {string} path - The full URL path without query or hash.
|
||||
* @property {Record<string, any>} query - Query parameters in the form of key-value pairs.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns an object representing the current route information.
|
||||
*
|
||||
* @returns {RouteObject} An object containing details about the current route.
|
||||
*/
|
||||
export function useRoute() {
|
||||
const currentRoute = computed(() => getCurrentInstance().proxy.$route)
|
||||
|
||||
const protoRoute = Object.keys(currentRoute.value).reduce(
|
||||
(acc, key) => {
|
||||
acc[key] = computed(() => currentRoute.value[key])
|
||||
return acc
|
||||
},
|
||||
{}
|
||||
)
|
||||
|
||||
// @ts-ignore
|
||||
return reactive(protoRoute)
|
||||
}
|
||||
|
||||
export function useRouter() {
|
||||
return getCurrentInstance().proxy.$router
|
||||
}
|
||||
|
||||
export default router
|
||||
|
||||
@@ -7,7 +7,7 @@ import errors from '@/store/modules/errors'
|
||||
|
||||
Vue.use(Vuex)
|
||||
|
||||
export default new Store({
|
||||
const storeInst = new Store({
|
||||
modules: {
|
||||
appInfo,
|
||||
login,
|
||||
@@ -15,3 +15,9 @@ export default new Store({
|
||||
},
|
||||
strict: process.env.NODE_ENV !== 'production'
|
||||
})
|
||||
|
||||
export function useStore() {
|
||||
return storeInst
|
||||
}
|
||||
|
||||
export default storeInst;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ref } from '@vue/composition-api'
|
||||
import { ref } from 'vue'
|
||||
import store from '@/store'
|
||||
import { fetchData } from '@/utils/api'
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ref } from '@vue/composition-api'
|
||||
import { ref } from 'vue'
|
||||
import { fetchData } from '@/utils/api'
|
||||
|
||||
const searchResult = ref({})
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ref } from '@vue/composition-api'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const isOnline = ref(navigator.onLine)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ref } from '@vue/composition-api'
|
||||
import { ref } from 'vue'
|
||||
import { fetchData } from '@/utils/api'
|
||||
|
||||
const result = ref({})
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ref, computed } from '@vue/composition-api'
|
||||
import { ref, computed } from 'vue'
|
||||
import store from '@/store'
|
||||
import { fetchData } from '@/utils/api'
|
||||
import { toast } from '@/utils/toasts'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ref, watch } from '@vue/composition-api'
|
||||
import { ref, watch } from 'vue'
|
||||
|
||||
/**
|
||||
* @typedef {string} Theme
|
||||
|
||||
Reference in New Issue
Block a user