新增全屏状态
parent
05f6a953ea
commit
3acc0931d8
1
FAQ.md
1
FAQ.md
|
@ -30,6 +30,7 @@
|
|||
- 在我的列表内可以使用`Ctrl + f`键打开搜索框进行列表内歌曲搜索,搜索框按`Esc`键可以关闭搜索框,搜索框内按上下方向键可以选择歌曲,按`回车`键跳转到已选歌曲,按`Ctrl + 回车`可以跳转并播放已选歌曲
|
||||
- 在我的列表按住`Ctrl`键可以进入**列表拖动模式**,此时可以用鼠标拖动列表调整列表的位置
|
||||
- 编辑列表名时按`Esc`键可以取消编辑
|
||||
- 按F11可以进入、退出全屏状态(v1.19.0新增)
|
||||
|
||||
## 歌曲无法试听与下载
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
- 新增对播放详情页歌词大小、是否缩放、对齐方式的设置,可以去设置-播放详情页设置查看
|
||||
- 新增播放详情页通过歌词调整播放进度,默认关闭,需要到设置-播放详情页设置开启,开启后在播放详情页拖动歌词时将会出现跳转当前行歌词播放的按钮
|
||||
- 新增全屏状态,按F11可以进入、退出全屏状态
|
||||
|
||||
### 优化
|
||||
|
||||
|
@ -32,3 +33,4 @@
|
|||
- 在我的列表内可以使用Ctrl+f键打开搜索框进行列表内歌曲搜索,搜索框按Esc键可以关闭搜索框,搜索框内按上下方向键可以选择歌曲,按回车键跳转到已选歌曲,按Ctrl+回车可以跳转并播放已选歌曲
|
||||
- 在我的列表按住Ctrl键可以进入列表拖动模式,此时可以用鼠标拖动列表调整列表的位置
|
||||
- 编辑列表名时按Esc键可以取消编辑
|
||||
- 按F11可以进入、退出全屏状态
|
||||
|
|
|
@ -4,6 +4,7 @@ const names = {
|
|||
close: 'close',
|
||||
min: 'min',
|
||||
max: 'max',
|
||||
fullscreen: 'fullscreen',
|
||||
set_app_name: 'set_app_name',
|
||||
clear_cache: 'clear_cache',
|
||||
get_cache_size: 'get_cache_size',
|
||||
|
|
|
@ -170,7 +170,7 @@ function createWindow() {
|
|||
// icon: path.join(global.__static, isWin ? 'icons/256x256.ico' : 'icons/512x512.png'),
|
||||
resizable: false,
|
||||
maximizable: false,
|
||||
fullscreenable: false,
|
||||
fullscreenable: true,
|
||||
show: false,
|
||||
webPreferences: {
|
||||
contextIsolation: false,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
const { app } = require('electron')
|
||||
const { mainOn, NAMES: { mainWindow: ipcMainWindowNames } } = require('../../common/ipc')
|
||||
const { mainOn, mainHandle, NAMES: { mainWindow: ipcMainWindowNames } } = require('../../common/ipc')
|
||||
|
||||
mainOn(ipcMainWindowNames.min, event => {
|
||||
if (global.modules.mainWindow) {
|
||||
|
@ -16,3 +16,8 @@ mainOn(ipcMainWindowNames.close, (event, isForce) => {
|
|||
global.isTrafficLightClose = true
|
||||
if (global.modules.mainWindow) global.modules.mainWindow.close()
|
||||
})
|
||||
mainHandle(ipcMainWindowNames.fullscreen, async(event, isFullscreen) => {
|
||||
if (!global.modules.mainWindow) return false
|
||||
await global.modules.mainWindow.setFullScreen(isFullscreen)
|
||||
return isFullscreen
|
||||
})
|
||||
|
|
|
@ -16,11 +16,23 @@
|
|||
<script>
|
||||
import { useRefGetter, watch, onMounted } from '@renderer/utils/vueTools'
|
||||
import useApp from '@renderer/core/useApp'
|
||||
import { isFullscreen } from '@renderer/core/share'
|
||||
|
||||
const getFontSizeWithScreen = screenWidth => {
|
||||
return screenWidth <= 1440
|
||||
? 16
|
||||
: screenWidth <= 1920
|
||||
? 18
|
||||
: screenWidth <= 2560
|
||||
? 20
|
||||
: screenWidth <= 2560 ? 20 : 22
|
||||
}
|
||||
|
||||
export default {
|
||||
setup() {
|
||||
const theme = useRefGetter('theme')
|
||||
const font = useRefGetter('font')
|
||||
const windowSizeActive = useRefGetter('windowSizeActive')
|
||||
|
||||
const dom_root = document.getElementById('root')
|
||||
|
||||
|
@ -34,6 +46,17 @@ export default {
|
|||
}, {
|
||||
immediate: true,
|
||||
})
|
||||
watch(isFullscreen, val => {
|
||||
if (val) {
|
||||
document.body.classList.remove(window.dt ? 'disableTransparent' : 'transparent')
|
||||
document.body.classList.add('fullscreen')
|
||||
document.documentElement.style.fontSize = getFontSizeWithScreen(window.screen.width) + 'px'
|
||||
} else {
|
||||
document.body.classList.remove('fullscreen')
|
||||
document.body.classList.add(window.dt ? 'disableTransparent' : 'transparent')
|
||||
document.documentElement.style.fontSize = windowSizeActive.value.fontSize
|
||||
}
|
||||
})
|
||||
|
||||
useApp()
|
||||
|
||||
|
@ -85,13 +108,13 @@ body {
|
|||
|
||||
.transparent {
|
||||
padding: @shadow-app;
|
||||
#waiting-mask {
|
||||
border-radius: @radius-border;
|
||||
left: @shadow-app;
|
||||
right: @shadow-app;
|
||||
top: @shadow-app;
|
||||
bottom: @shadow-app;
|
||||
}
|
||||
// #waiting-mask {
|
||||
// border-radius: @radius-border;
|
||||
// left: @shadow-app;
|
||||
// right: @shadow-app;
|
||||
// top: @shadow-app;
|
||||
// bottom: @shadow-app;
|
||||
// }
|
||||
#root {
|
||||
box-shadow: 0 0 @shadow-app rgba(0, 0, 0, 0.5);
|
||||
border-radius: @radius-border;
|
||||
|
@ -114,6 +137,14 @@ body {
|
|||
margin-right: 5Px;
|
||||
}
|
||||
}
|
||||
.fullscreen {
|
||||
background-color: #fff;
|
||||
|
||||
#right {
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
#container {
|
||||
position: relative;
|
||||
|
|
|
@ -26,16 +26,26 @@ const themes = {
|
|||
naruto: 'rgba(87,144,167,.14)',
|
||||
happy_new_year: 'rgba(192,57,43,.1)',
|
||||
}
|
||||
|
||||
const getBarWidth = canvasWidth => {
|
||||
let barWidth = (canvasWidth / 128) * 2.5
|
||||
const width = canvasWidth / 85
|
||||
// console.log(barWidth - width)
|
||||
// if (barWidth - width > 20) newBarWidth = 20
|
||||
// barWidth = newBarWidth
|
||||
return barWidth - width > 12 ? width : barWidth
|
||||
}
|
||||
export default {
|
||||
setup() {
|
||||
const dom_canvas = ref(null)
|
||||
const analyser = getAnalyser()
|
||||
|
||||
let ctx
|
||||
let bufferLength
|
||||
let bufferLength = 0
|
||||
let dataArray
|
||||
let WIDTH
|
||||
let HEIGHT
|
||||
let MAX_HEIGHT
|
||||
let barWidth
|
||||
let barHeight
|
||||
let x = 0
|
||||
|
@ -89,7 +99,7 @@ export default {
|
|||
// let b = 50
|
||||
|
||||
// ctx.fillStyle = 'rgb(' + r + ',' + g + ',' + b + ')'
|
||||
barHeight = barHeight * frequencyAvg + barHeight * 0.42
|
||||
barHeight = (barHeight * frequencyAvg + barHeight * 0.42) * MAX_HEIGHT
|
||||
ctx.fillRect(x, HEIGHT - barHeight, barWidth, barHeight)
|
||||
|
||||
x += barWidth
|
||||
|
@ -101,7 +111,7 @@ export default {
|
|||
analyser.fftSize = 256
|
||||
bufferLength = analyser.frequencyBinCount
|
||||
// console.log(bufferLength)
|
||||
barWidth = (WIDTH / bufferLength) * 2.5
|
||||
barWidth = getBarWidth(WIDTH)
|
||||
dataArray = new Uint8Array(bufferLength)
|
||||
renderFrame()
|
||||
}
|
||||
|
@ -110,14 +120,27 @@ export default {
|
|||
isPlaying = false
|
||||
}
|
||||
|
||||
const handleResize = () => {
|
||||
const canvas = dom_canvas.value
|
||||
canvas.width = canvas.clientWidth
|
||||
canvas.height = canvas.clientHeight
|
||||
WIDTH = canvas.width
|
||||
HEIGHT = canvas.height
|
||||
MAX_HEIGHT = Math.round(HEIGHT * 0.4 / 255 * 10000) / 10000
|
||||
// console.log(MAX_HEIGHT)
|
||||
barWidth = getBarWidth(WIDTH)
|
||||
}
|
||||
|
||||
window.eventHub.on(eventPlayerNames.play, handlePlay)
|
||||
window.eventHub.on(eventPlayerNames.pause, handlePause)
|
||||
window.eventHub.on(eventPlayerNames.error, handlePause)
|
||||
window.addEventListener('resize', handleResize)
|
||||
onBeforeUnmount(() => {
|
||||
handlePause()
|
||||
window.eventHub.off(eventPlayerNames.play, handlePlay)
|
||||
window.eventHub.off(eventPlayerNames.pause, handlePause)
|
||||
window.eventHub.off(eventPlayerNames.error, handlePause)
|
||||
window.removeEventListener('resize', handleResize)
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
|
@ -127,6 +150,8 @@ export default {
|
|||
canvas.height = canvas.clientHeight
|
||||
WIDTH = canvas.width
|
||||
HEIGHT = canvas.height
|
||||
MAX_HEIGHT = Math.round(HEIGHT * 0.4 / 255 * 10000) / 10000
|
||||
// console.log(MAX_HEIGHT)
|
||||
if (isPlay.value) handlePlay()
|
||||
})
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div :class="$style.controlBtn">
|
||||
<div :class="$style.controlBtn" v-show="!isFullscreen">
|
||||
<button type="button" :class="[$style.btn, $style.close]" :tips="$t('close')" @click="close">
|
||||
<svg :class="$style.controlBtniIcon" version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" width="100%" viewBox="0 0 24 24" space="preserve">
|
||||
<use xlink:href="#icon-window-close"></use>
|
||||
|
@ -16,10 +16,12 @@
|
|||
<script>
|
||||
import { base as eventBaseName } from '@renderer/event/names'
|
||||
// import { getRandom } from '../../utils'
|
||||
import { isFullscreen } from '@renderer/core/share'
|
||||
|
||||
export default {
|
||||
setup() {
|
||||
return {
|
||||
isFullscreen,
|
||||
min() {
|
||||
window.eventHub.emit(eventBaseName.min)
|
||||
},
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div :class="$style.menu">
|
||||
<ul :class="$style.list">
|
||||
<li v-for="item in menus" :key="item.to">
|
||||
<li v-for="item in menus" :key="item.to" :class="$style.navItem">
|
||||
<router-link :class="$style.link" :active-class="$style.active" :to="item.to" :tips="item.tips">
|
||||
<div :class="$style.icon">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" :viewBox="item.iconSize" space="preserve">
|
||||
|
@ -98,13 +98,26 @@ export default {
|
|||
// .mixin-ellipsis-1;
|
||||
// }
|
||||
}
|
||||
.link {
|
||||
.navItem {
|
||||
position: relative;
|
||||
&:before {
|
||||
content: '';
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding-bottom: 84%;
|
||||
}
|
||||
}
|
||||
.link {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
// display: block;
|
||||
box-sizing: border-box;
|
||||
text-decoration: none;
|
||||
|
||||
position: relative;
|
||||
padding: 18px 3px;
|
||||
// padding: 18px 3px;
|
||||
// margin: 5px 0;
|
||||
// border-left: 5px solid transparent;
|
||||
transition: @transition-theme;
|
||||
|
@ -114,6 +127,9 @@ export default {
|
|||
font-size: 11.5px;
|
||||
text-align: center;
|
||||
outline: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
transition: background-color 0.3s ease;
|
||||
// border-radius: @radius-border;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div :class="$style.aside">
|
||||
<div :class="[$style.aside, { [$style.fullscreen]: isFullscreen }]">
|
||||
<ControlBtns v-if="setting.controlBtnPosition == 'left'" />
|
||||
<div :class="$style.logo" v-else>L X</div>
|
||||
<NavBar />
|
||||
|
@ -8,6 +8,7 @@
|
|||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import { isFullscreen } from '@renderer/core/share'
|
||||
|
||||
import ControlBtns from './ControlBtns'
|
||||
import NavBar from './NavBar'
|
||||
|
@ -15,6 +16,11 @@ import NavBar from './NavBar'
|
|||
export default {
|
||||
name: 'CoreAside',
|
||||
components: { ControlBtns, NavBar },
|
||||
setup() {
|
||||
return {
|
||||
isFullscreen,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['setting']),
|
||||
},
|
||||
|
@ -36,6 +42,13 @@ export default {
|
|||
-webkit-user-select: none;
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
|
||||
&.fullscreen {
|
||||
-webkit-app-region: no-drag;
|
||||
.logo {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.logo {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template lang="pug">
|
||||
transition(enter-active-class="animated lightSpeedIn" leave-active-class="animated slideOutDown" @after-enter="handleAfterEnter" @after-leave="handleAfterLeave")
|
||||
div(:class="$style.container" @contextmenu="handleContextMenu" v-if="isShowPlayerDetail")
|
||||
div(:class="[$style.container, , { [$style.fullscreen]: isFullscreen }]" @contextmenu="handleContextMenu" v-if="isShowPlayerDetail")
|
||||
//- div(:class="$style.bg" :style="bgStyle")
|
||||
//- div(:class="$style.bg2")
|
||||
div(:class="[$style.header, $style.controlBtnLeft]" v-if="setting.controlBtnPosition == 'left'")
|
||||
|
@ -52,6 +52,7 @@ transition(enter-active-class="animated lightSpeedIn" leave-active-class="animat
|
|||
|
||||
<script>
|
||||
import { useRefGetter, ref } from '@renderer/utils/vueTools'
|
||||
import { isFullscreen } from '@renderer/core/share'
|
||||
import { base as eventBaseName } from '@renderer/event/names'
|
||||
import {
|
||||
isShowPlayerDetail,
|
||||
|
@ -117,6 +118,7 @@ export default {
|
|||
handleAfterEnter,
|
||||
handleAfterLeave,
|
||||
visibled,
|
||||
isFullscreen,
|
||||
min() {
|
||||
window.eventHub.emit(eventBaseName.min)
|
||||
},
|
||||
|
@ -161,6 +163,15 @@ export default {
|
|||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
&.fullscreen {
|
||||
.header {
|
||||
-webkit-app-region: no-drag;
|
||||
.close, .min {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// .bg {
|
||||
// position: absolute;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div :class="$style.control">
|
||||
<div :class="$style.control" v-show="!isFullscreen">
|
||||
<button type="button" :class="[$style.btn, $style.min]" :tips="$t('min')" @click="min">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" height="60%" viewBox="0 0 24 24" space="preserve">
|
||||
<use xlink:href="#icon-window-minimize-2"></use>
|
||||
|
@ -15,6 +15,7 @@
|
|||
|
||||
<script>
|
||||
import { base as eventBaseName } from '@renderer/event/names'
|
||||
import { isFullscreen } from '@renderer/core/share'
|
||||
// import { getRandom } from '../../utils'
|
||||
|
||||
export default {
|
||||
|
@ -29,6 +30,7 @@ export default {
|
|||
close() {
|
||||
window.eventHub.emit(eventBaseName.close)
|
||||
},
|
||||
isFullscreen,
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div :class="[$style.toolbar, setting.controlBtnPosition == 'left' ? $style.controlBtnLeft : $style.controlBtnRight]">
|
||||
<div :class="[$style.toolbar, { [$style.fullscreen]: isFullscreen }, setting.controlBtnPosition == 'left' ? $style.controlBtnLeft : $style.controlBtnRight]">
|
||||
<SearchInput />
|
||||
<div :class="$style.logo" v-if="setting.controlBtnPosition == 'left'">L X</div>
|
||||
<ControlBtns v-else />
|
||||
|
@ -11,10 +11,16 @@ import { mapGetters } from 'vuex'
|
|||
|
||||
import ControlBtns from './ControlBtns'
|
||||
import SearchInput from './SearchInput'
|
||||
import { isFullscreen } from '@renderer/core/share'
|
||||
|
||||
export default {
|
||||
name: 'CoreToolBar',
|
||||
components: { SearchInput, ControlBtns },
|
||||
setup() {
|
||||
return {
|
||||
isFullscreen,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['setting']),
|
||||
},
|
||||
|
@ -34,6 +40,13 @@ export default {
|
|||
-webkit-app-region: drag;
|
||||
z-index: 2;
|
||||
|
||||
&.fullscreen {
|
||||
-webkit-app-region: no-drag;
|
||||
.logo {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.controlBtnLeft {
|
||||
.control {
|
||||
display: none;
|
||||
|
|
|
@ -36,6 +36,7 @@ export const sync = window.sync = reactive({
|
|||
devices: [],
|
||||
},
|
||||
})
|
||||
export const isFullscreen = ref(false)
|
||||
|
||||
export const windowSizeList = markRaw(configWindowSizeList)
|
||||
export const themes = markRaw(configThemes)
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { openUrl } from '@renderer/utils'
|
||||
import { base as eventBaseName } from '@renderer/event/names'
|
||||
import { onSetConfig } from '@renderer/utils/tools'
|
||||
import { isFullscreen } from '@renderer/core/share'
|
||||
import { rendererSend, NAMES, rendererInvoke } from '@common/ipc'
|
||||
|
||||
import {
|
||||
toRaw,
|
||||
|
@ -22,6 +24,14 @@ const handleBodyClick = event => {
|
|||
event.preventDefault()
|
||||
if (/^https?:\/\//.test(event.target.href)) openUrl(event.target.href)
|
||||
}
|
||||
const handle_open_devtools = event => {
|
||||
rendererSend(NAMES.mainWindow.open_dev_tools)
|
||||
}
|
||||
const handle_fullscreen = event => {
|
||||
rendererInvoke(NAMES.mainWindow.fullscreen, !isFullscreen.value).then(fullscreen => {
|
||||
isFullscreen.value = fullscreen
|
||||
})
|
||||
}
|
||||
|
||||
export default ({
|
||||
dieableIgnoreMouseEvents,
|
||||
|
@ -56,6 +66,8 @@ export default ({
|
|||
|
||||
window.eventHub.emit(eventBaseName.bindKey)
|
||||
window.eventHub.on('key_escape_down', handle_key_esc_down)
|
||||
window.eventHub.on('key_mod+f12_down', handle_open_devtools)
|
||||
window.eventHub.on('key_f11_down', handle_fullscreen)
|
||||
document.body.addEventListener('click', handleBodyClick, true)
|
||||
|
||||
if (isProd && !window.dt && !isLinux) {
|
||||
|
@ -68,6 +80,8 @@ export default ({
|
|||
|
||||
onBeforeUnmount(() => {
|
||||
window.eventHub.off('key_escape_down', handle_key_esc_down)
|
||||
window.eventHub.off('key_mod+f12_down', handle_open_devtools)
|
||||
window.eventHub.off('key_f11_down', handle_fullscreen)
|
||||
document.body.removeEventListener('click', handleBodyClick)
|
||||
window.eventHub.emit(eventBaseName.unbindKey)
|
||||
rSetConfig()
|
||||
|
|
|
@ -106,7 +106,3 @@ eventHub.on(syncName.send_sync_list, ({ action, data }) => {
|
|||
if (!sync.enable) return
|
||||
rendererSend(NAMES.mainWindow.sync_list, { action, data })
|
||||
})
|
||||
eventHub.on('key_mod+f12_down', ({ action, data }) => {
|
||||
if (!sync.enable) return
|
||||
rendererSend(NAMES.mainWindow.open_dev_tools)
|
||||
})
|
||||
|
|
|
@ -32,7 +32,7 @@ dd(:tips="$t('setting__basic_window_size_title')")
|
|||
h3#basic_window_size {{$t('setting__basic_window_size')}}
|
||||
div
|
||||
base-checkbox.gap-left(v-for="(item, index) in windowSizeList" :id="`setting_window_size_${item.id}`" name="setting_window_size"
|
||||
need v-model="currentStting.windowSizeId" :value="item.id" :label="$t('setting__basic_window_size_' + item.name)" :key="item.id")
|
||||
need v-model="currentStting.windowSizeId" :disabled="isFullscreen" :value="item.id" :label="$t('setting__basic_window_size_' + item.name)" :key="item.id")
|
||||
|
||||
dd(:tips="$t('setting__basic_lang_title')")
|
||||
h3#basic_lang {{$t('setting__basic_lang')}}
|
||||
|
@ -61,7 +61,7 @@ user-api-modal(v-model="isShowUserApiModal")
|
|||
|
||||
<script>
|
||||
import { computed, ref, useI18n, watch } from '@renderer/utils/vueTools'
|
||||
import { themes as themeList, windowSizeList, apiSource, userApi } from '@renderer/core/share'
|
||||
import { themes as themeList, windowSizeList, apiSource, userApi, isFullscreen } from '@renderer/core/share'
|
||||
import { langList } from '@/lang'
|
||||
import { currentStting } from '../setting'
|
||||
import { setWindowSize } from '@renderer/utils'
|
||||
|
@ -170,6 +170,7 @@ export default {
|
|||
sourceNameTypes,
|
||||
controlBtnPositionList,
|
||||
fontList,
|
||||
isFullscreen,
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue