新增任务栏缩略图工具栏控制按钮
|
@ -3,6 +3,7 @@
|
||||||
- 新增“双击列表里的歌曲时自动切换到当前列表播放”设置,此功能仅对歌单、排行榜有效,默认关闭
|
- 新增“双击列表里的歌曲时自动切换到当前列表播放”设置,此功能仅对歌单、排行榜有效,默认关闭
|
||||||
- 新增打开收藏的在线列表的对应平台详情页功能,可以在我的列表-列表右键菜单中使用
|
- 新增打开收藏的在线列表的对应平台详情页功能,可以在我的列表-列表右键菜单中使用
|
||||||
- 新增定时暂停播放功能,由于此功能大多数人可能不常用,所以将其放在设置-基本设置中
|
- 新增定时暂停播放功能,由于此功能大多数人可能不常用,所以将其放在设置-基本设置中
|
||||||
|
- 新增任务栏缩略图工具栏控制按钮(此功能仅在Windows平台可用),按钮分别为收藏/取消收藏(将歌曲添加到“我的收藏”列表)、上一曲、播放/暂停、下一曲
|
||||||
- 新增设置-基本设置-软件字体设置,此设置可用于设置主界面的字体(已知的问题:Windows 7 下可能会出现字体列表为空的情况,这是当前系统的 Powershell 版本小于5.1导致的,请自行尝试看常见解决)
|
- 新增设置-基本设置-软件字体设置,此设置可用于设置主界面的字体(已知的问题:Windows 7 下可能会出现字体列表为空的情况,这是当前系统的 Powershell 版本小于5.1导致的,请自行尝试看常见解决)
|
||||||
- 新增Scheme URL对音乐搜索的调用支持,详情看常见问题-Scheme URL支持
|
- 新增Scheme URL对音乐搜索的调用支持,详情看常见问题-Scheme URL支持
|
||||||
- 新增Scheme URL以url传参的方式调用,详情看常见问题-Scheme URL支持
|
- 新增Scheme URL以url传参的方式调用,详情看常见问题-Scheme URL支持
|
||||||
|
|
|
@ -86,6 +86,9 @@ const names = {
|
||||||
sync_action_list: 'sync_action_list',
|
sync_action_list: 'sync_action_list',
|
||||||
sync_list: 'sync_list',
|
sync_list: 'sync_list',
|
||||||
|
|
||||||
|
taskbar_set_thumbar_buttons: 'taskbar_set_thumbar_buttons',
|
||||||
|
taskbar_set_thumbnail_clip: 'taskbar_set_thumbnail_clip',
|
||||||
|
taskbar_on_thumbar_button_click: 'taskbar_on_thumbar_button_click',
|
||||||
},
|
},
|
||||||
winLyric: {
|
winLyric: {
|
||||||
close: 'close',
|
close: 'close',
|
||||||
|
|
|
@ -6,6 +6,7 @@ const Tray = require('./Tray')
|
||||||
const WinLyric = require('./WinLyric')
|
const WinLyric = require('./WinLyric')
|
||||||
const HotKey = require('./HotKey')
|
const HotKey = require('./HotKey')
|
||||||
|
|
||||||
|
const { Event: TaskBar } = require('../modules/taskbar')
|
||||||
const { Event: UserApi } = require('../modules/userApi')
|
const { Event: UserApi } = require('../modules/userApi')
|
||||||
const { Event: Sync } = require('../modules/sync')
|
const { Event: Sync } = require('../modules/sync')
|
||||||
|
|
||||||
|
@ -15,5 +16,6 @@ if (!global.lx_event.tray) global.lx_event.tray = new Tray()
|
||||||
if (!global.lx_event.winLyric) global.lx_event.winLyric = new WinLyric()
|
if (!global.lx_event.winLyric) global.lx_event.winLyric = new WinLyric()
|
||||||
if (!global.lx_event.hotKey) global.lx_event.hotKey = new HotKey()
|
if (!global.lx_event.hotKey) global.lx_event.hotKey = new HotKey()
|
||||||
|
|
||||||
|
if (!global.lx_event.taskbar) global.lx_event.taskbar = new TaskBar()
|
||||||
if (!global.lx_event.userApi) global.lx_event.userApi = new UserApi()
|
if (!global.lx_event.userApi) global.lx_event.userApi = new UserApi()
|
||||||
if (!global.lx_event.sync) global.lx_event.sync = new Sync()
|
if (!global.lx_event.sync) global.lx_event.sync = new Sync()
|
||||||
|
|
|
@ -2,4 +2,3 @@ require('./appMenu')
|
||||||
require('./winLyric')
|
require('./winLyric')
|
||||||
require('./tray')
|
require('./tray')
|
||||||
require('./hotKey')
|
require('./hotKey')
|
||||||
require('./userApi')
|
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
const { EventEmitter } = require('events')
|
||||||
|
const TASKBAR_EVENT_NAME = require('./name')
|
||||||
|
|
||||||
|
class TaskBar extends EventEmitter {
|
||||||
|
thumbarButtonClick(type) {
|
||||||
|
this.emit(TASKBAR_EVENT_NAME.thumbarButtonClick, type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = TaskBar
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = {
|
||||||
|
thumbarButtonClick: 'thumbarButtonClick',
|
||||||
|
}
|
|
@ -0,0 +1,92 @@
|
||||||
|
const path = require('path')
|
||||||
|
const Event = require('./event/event')
|
||||||
|
const eventNames = require('./event/name')
|
||||||
|
|
||||||
|
exports.Event = Event
|
||||||
|
exports.eventNames = eventNames
|
||||||
|
|
||||||
|
exports.setThumbnailClip = (region = { x: 0, y: 0, width: 0, height: 0 }) => {
|
||||||
|
if (!global.modules.mainWindow) return
|
||||||
|
return global.modules.mainWindow.setThumbnailClip(region)
|
||||||
|
}
|
||||||
|
|
||||||
|
const getIconPath = name => {
|
||||||
|
return path.join(global.__static, 'images/taskbar', name + '.png')
|
||||||
|
}
|
||||||
|
|
||||||
|
const buttonsFlags = {
|
||||||
|
empty: false,
|
||||||
|
collect: false,
|
||||||
|
play: false,
|
||||||
|
next: true,
|
||||||
|
prev: true,
|
||||||
|
}
|
||||||
|
const createButtons = ({ empty = false, collect = false, play = false, next = true, prev = true }) => {
|
||||||
|
const buttons = [
|
||||||
|
collect
|
||||||
|
? {
|
||||||
|
icon: getIconPath('collected'),
|
||||||
|
click() {
|
||||||
|
global.lx_event.taskbar.thumbarButtonClick('unCollect')
|
||||||
|
},
|
||||||
|
tooltip: '取消收藏',
|
||||||
|
flags: ['nobackground'],
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
icon: getIconPath('collect'),
|
||||||
|
click() {
|
||||||
|
global.lx_event.taskbar.thumbarButtonClick('collect')
|
||||||
|
},
|
||||||
|
tooltip: '收藏',
|
||||||
|
flags: ['nobackground'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: getIconPath('prev'),
|
||||||
|
click() {
|
||||||
|
global.lx_event.taskbar.thumbarButtonClick('prev')
|
||||||
|
},
|
||||||
|
tooltip: '上一曲',
|
||||||
|
flags: prev ? ['nobackground'] : ['nobackground', 'disabled'],
|
||||||
|
},
|
||||||
|
play
|
||||||
|
? {
|
||||||
|
icon: getIconPath('pause'),
|
||||||
|
click() {
|
||||||
|
global.lx_event.taskbar.thumbarButtonClick('pause')
|
||||||
|
},
|
||||||
|
tooltip: '暂停',
|
||||||
|
flags: ['nobackground'],
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
icon: getIconPath('play'),
|
||||||
|
click() {
|
||||||
|
global.lx_event.taskbar.thumbarButtonClick('play')
|
||||||
|
},
|
||||||
|
tooltip: '播放',
|
||||||
|
flags: ['nobackground'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: getIconPath('next'),
|
||||||
|
click() {
|
||||||
|
global.lx_event.taskbar.thumbarButtonClick('next')
|
||||||
|
},
|
||||||
|
tooltip: '下一曲',
|
||||||
|
flags: next ? ['nobackground'] : ['nobackground', 'disabled'],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
if (empty) {
|
||||||
|
for (const button of buttons) {
|
||||||
|
button.flags = ['nobackground', 'disabled']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buttons
|
||||||
|
}
|
||||||
|
exports.setThumbarButtons = ({ empty, collect, play, next, prev } = buttonsFlags) => {
|
||||||
|
if (!global.modules.mainWindow) return
|
||||||
|
buttonsFlags.empty = empty
|
||||||
|
buttonsFlags.collect = collect
|
||||||
|
buttonsFlags.play = play
|
||||||
|
buttonsFlags.next = next
|
||||||
|
buttonsFlags.prev = prev
|
||||||
|
global.modules.mainWindow.setThumbarButtons(createButtons(buttonsFlags))
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
|
const { isWin } = require('@common/utils')
|
||||||
// require('./request')
|
// require('./request')
|
||||||
// require('./appName')
|
// require('./appName')
|
||||||
require('./progressBar')
|
require('./progressBar')
|
||||||
|
@ -23,6 +23,8 @@ require('./systemFonts')
|
||||||
require('./wait')
|
require('./wait')
|
||||||
require('./openDevtools')
|
require('./openDevtools')
|
||||||
|
|
||||||
|
if (isWin) require('./taskbar')
|
||||||
|
|
||||||
// require('./kw_decodeLyric')
|
// require('./kw_decodeLyric')
|
||||||
|
|
||||||
require('./userApi')
|
require('./userApi')
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
const { mainSend, mainOn, NAMES: { mainWindow: ipcMainWindowNames }, mainHandle } = require('@common/ipc')
|
||||||
|
const { setThumbnailClip, setThumbarButtons, eventNames } = require('../modules/taskbar')
|
||||||
|
const { mainWindow: MAIN_WINDOW_EVENT_NAME } = require('@main/events/_name')
|
||||||
|
|
||||||
|
const handleThumbarButtonClick = action => {
|
||||||
|
mainSend(global.modules.mainWindow, ipcMainWindowNames.taskbar_on_thumbar_button_click, action)
|
||||||
|
}
|
||||||
|
|
||||||
|
global.lx_event.taskbar.on(eventNames.thumbarButtonClick, handleThumbarButtonClick)
|
||||||
|
global.lx_event.mainWindow.on(MAIN_WINDOW_EVENT_NAME.show, setThumbarButtons)
|
||||||
|
|
||||||
|
mainHandle(ipcMainWindowNames.taskbar_set_thumbnail_clip, (event, clip) => {
|
||||||
|
return setThumbnailClip(clip)
|
||||||
|
})
|
||||||
|
|
||||||
|
mainOn(ipcMainWindowNames.taskbar_set_thumbar_buttons, (event, buttons) => {
|
||||||
|
setThumbarButtons(buttons)
|
||||||
|
})
|
|
@ -40,7 +40,7 @@ export default () => {
|
||||||
isProd,
|
isProd,
|
||||||
isLinux,
|
isLinux,
|
||||||
})
|
})
|
||||||
usePlayer({ setting })
|
const initPlayer = usePlayer({ setting })
|
||||||
const handleEnvParams = useHandleEnvParams()
|
const handleEnvParams = useHandleEnvParams()
|
||||||
const initData = useDataInit({
|
const initData = useDataInit({
|
||||||
setting,
|
setting,
|
||||||
|
@ -60,6 +60,7 @@ export default () => {
|
||||||
|
|
||||||
// 初始化我的列表、下载列表等数据
|
// 初始化我的列表、下载列表等数据
|
||||||
initData().then(() => {
|
initData().then(() => {
|
||||||
|
initPlayer()
|
||||||
handleEnvParams(envParams) // 处理传入的启动参数
|
handleEnvParams(envParams) // 处理传入的启动参数
|
||||||
initDeepLink(envParams)
|
initDeepLink(envParams)
|
||||||
})
|
})
|
||||||
|
|
|
@ -4,6 +4,7 @@ import {
|
||||||
import useMediaDevice from './useMediaDevice'
|
import useMediaDevice from './useMediaDevice'
|
||||||
import usePlayerEvent from './usePlayerEvent'
|
import usePlayerEvent from './usePlayerEvent'
|
||||||
import usePlayer from './usePlayer'
|
import usePlayer from './usePlayer'
|
||||||
|
import useTaskbar from './useTaskbar'
|
||||||
import { init as initPlayTimeoutStop } from '@renderer/utils/timeoutStop'
|
import { init as initPlayTimeoutStop } from '@renderer/utils/timeoutStop'
|
||||||
|
|
||||||
export default ({ setting }) => {
|
export default ({ setting }) => {
|
||||||
|
@ -12,7 +13,12 @@ export default ({ setting }) => {
|
||||||
usePlayerEvent()
|
usePlayerEvent()
|
||||||
useMediaDevice({ setting }) // 初始化音频驱动输出设置
|
useMediaDevice({ setting }) // 初始化音频驱动输出设置
|
||||||
usePlayer({ setting })
|
usePlayer({ setting })
|
||||||
|
const initTaskbar = useTaskbar()
|
||||||
|
|
||||||
initPlayTimeoutStop()
|
initPlayTimeoutStop()
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
initTaskbar()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -195,11 +195,9 @@ export default ({ setting }) => {
|
||||||
|
|
||||||
const setPlayStatus = () => {
|
const setPlayStatus = () => {
|
||||||
setPlay(true)
|
setPlay(true)
|
||||||
setTitle(`${musicInfo.name} - ${musicInfo.singer}`)
|
|
||||||
}
|
}
|
||||||
const setPauseStatus = () => {
|
const setPauseStatus = () => {
|
||||||
setPlay(false)
|
setPlay(false)
|
||||||
setTitle()
|
|
||||||
if (global.isPlayedStop) handlePause()
|
if (global.isPlayedStop) handlePause()
|
||||||
}
|
}
|
||||||
const setStopStatus = () => {
|
const setStopStatus = () => {
|
||||||
|
@ -282,6 +280,7 @@ export default ({ setting }) => {
|
||||||
name: musicInfo.name,
|
name: musicInfo.name,
|
||||||
album: musicInfo.albumName,
|
album: musicInfo.albumName,
|
||||||
})
|
})
|
||||||
|
setTitle(`${musicInfo.name} - ${musicInfo.singer}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handelStop = () => {
|
const handelStop = () => {
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
import { onBeforeUnmount, useCommit } from '@renderer/utils/vueTools'
|
||||||
|
import { player as eventPlayerNames, taskbar as eventTaskbarNames } from '@renderer/event/names'
|
||||||
|
import { onTaskbarThumbarClick, setTaskbarThumbnailClip, setTaskbarThumbarButtons } from '@renderer/utils/tools'
|
||||||
|
// import store from '@renderer/store'
|
||||||
|
|
||||||
|
import { loveList, getList } from '@renderer/core/share/list'
|
||||||
|
import { playMusicInfo } from '@renderer/core/share/player'
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
const listAdd = useCommit('list', 'listAdd')
|
||||||
|
const listRemove = useCommit('list', 'listRemove')
|
||||||
|
// const setVisibleDesktopLyric = useCommit('setVisibleDesktopLyric')
|
||||||
|
// const setLockDesktopLyric = useCommit('setLockDesktopLyric')
|
||||||
|
|
||||||
|
const buttons = {
|
||||||
|
empty: false,
|
||||||
|
collect: false,
|
||||||
|
play: false,
|
||||||
|
prev: true,
|
||||||
|
next: true,
|
||||||
|
lrc: false,
|
||||||
|
lockLrc: false,
|
||||||
|
}
|
||||||
|
const setButtons = () => {
|
||||||
|
setTaskbarThumbarButtons(buttons)
|
||||||
|
}
|
||||||
|
const updateCollectStatus = () => {
|
||||||
|
let status = getList(loveList.id).some(musicInfo => playMusicInfo.musicInfo.songmid == musicInfo.songmid)
|
||||||
|
if (buttons.collect == status) return false
|
||||||
|
buttons.collect = status
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
const handlePlay = () => {
|
||||||
|
if (buttons.empty) buttons.empty = false
|
||||||
|
buttons.play = true
|
||||||
|
setButtons()
|
||||||
|
}
|
||||||
|
const handlePause = () => {
|
||||||
|
if (buttons.empty) buttons.empty = false
|
||||||
|
buttons.play = false
|
||||||
|
setButtons()
|
||||||
|
}
|
||||||
|
const handleStop = () => {
|
||||||
|
if (playMusicInfo.musicInfo != null) return
|
||||||
|
buttons.empty = true
|
||||||
|
setButtons()
|
||||||
|
}
|
||||||
|
const handleSetPlayInfo = () => {
|
||||||
|
if (!updateCollectStatus()) return
|
||||||
|
setButtons()
|
||||||
|
}
|
||||||
|
const handleSetTaskbarThumbnailClip = (clip) => {
|
||||||
|
setTaskbarThumbnailClip(clip)
|
||||||
|
}
|
||||||
|
// const updateSetting = () => {
|
||||||
|
// const setting = store.getters.setting
|
||||||
|
// buttons.lrc = setting.desktopLyric.enable
|
||||||
|
// buttons.lockLrc = setting.desktopLyric.isLock
|
||||||
|
// setButtons()
|
||||||
|
// }
|
||||||
|
const rTaskbarThumbarClick = onTaskbarThumbarClick((event, action) => {
|
||||||
|
switch (action) {
|
||||||
|
case 'play':
|
||||||
|
window.eventHub.emit(eventPlayerNames.setPlay)
|
||||||
|
break
|
||||||
|
case 'pause':
|
||||||
|
window.eventHub.emit(eventPlayerNames.setPause)
|
||||||
|
break
|
||||||
|
case 'prev':
|
||||||
|
window.eventHub.emit(eventPlayerNames.setPlayPrev)
|
||||||
|
break
|
||||||
|
case 'next':
|
||||||
|
window.eventHub.emit(eventPlayerNames.setPlayNext)
|
||||||
|
break
|
||||||
|
case 'collect':
|
||||||
|
if (!playMusicInfo.musicInfo) return
|
||||||
|
listAdd({ id: loveList.id, musicInfo: playMusicInfo.musicInfo })
|
||||||
|
if (updateCollectStatus()) setButtons()
|
||||||
|
break
|
||||||
|
case 'unCollect':
|
||||||
|
if (!playMusicInfo.musicInfo) return
|
||||||
|
listRemove({ listId: loveList.id, id: playMusicInfo.musicInfo.songmid })
|
||||||
|
if (updateCollectStatus()) setButtons()
|
||||||
|
break
|
||||||
|
// case 'lrc':
|
||||||
|
// setVisibleDesktopLyric(true)
|
||||||
|
// updateSetting()
|
||||||
|
// break
|
||||||
|
// case 'unLrc':
|
||||||
|
// setVisibleDesktopLyric(false)
|
||||||
|
// updateSetting()
|
||||||
|
// break
|
||||||
|
// case 'lockLrc':
|
||||||
|
// setLockDesktopLyric(true)
|
||||||
|
// updateSetting()
|
||||||
|
// break
|
||||||
|
// case 'unlockLrc':
|
||||||
|
// setLockDesktopLyric(false)
|
||||||
|
// updateSetting()
|
||||||
|
// break
|
||||||
|
}
|
||||||
|
})
|
||||||
|
window.eventHub.on(eventPlayerNames.play, handlePlay)
|
||||||
|
window.eventHub.on(eventPlayerNames.pause, handlePause)
|
||||||
|
window.eventHub.on(eventPlayerNames.stop, handleStop)
|
||||||
|
window.eventHub.on(eventPlayerNames.setPlayInfo, handleSetPlayInfo)
|
||||||
|
window.eventHub.on(eventTaskbarNames.setTaskbarThumbnailClip, handleSetTaskbarThumbnailClip)
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
rTaskbarThumbarClick()
|
||||||
|
window.eventHub.off(eventPlayerNames.play, handlePlay)
|
||||||
|
window.eventHub.off(eventPlayerNames.pause, handlePause)
|
||||||
|
window.eventHub.off(eventPlayerNames.stop, handleStop)
|
||||||
|
window.eventHub.off(eventPlayerNames.setPlayInfo, handleSetPlayInfo)
|
||||||
|
window.eventHub.off(eventTaskbarNames.setTaskbarThumbnailClip, handleSetTaskbarThumbnailClip)
|
||||||
|
})
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
// const setting = store.getters.setting
|
||||||
|
// buttons.lrc = setting.desktopLyric.enable
|
||||||
|
// buttons.lockLrc = setting.desktopLyric.isLock
|
||||||
|
setButtons()
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,9 +27,9 @@ const names = {
|
||||||
|
|
||||||
playMusic: 'playMusic',
|
playMusic: 'playMusic',
|
||||||
|
|
||||||
setPlayInfo: 'setPlayInfo',
|
setPlayInfo: 'setPlayInfo', // 设置播放信息
|
||||||
updatePic: 'updatePic',
|
updatePic: 'updatePic', // 更新图片事件
|
||||||
updateLyric: 'updateLyric',
|
updateLyric: 'updateLyric', // 更新歌词事件
|
||||||
|
|
||||||
activeTransition: 'activeTransition', // 激活进度条动画事件
|
activeTransition: 'activeTransition', // 激活进度条动画事件
|
||||||
playedStop: 'playedStop', // 定时停止事件
|
playedStop: 'playedStop', // 定时停止事件
|
||||||
|
@ -66,6 +66,9 @@ const names = {
|
||||||
send_sync_list: 'send_sync_list',
|
send_sync_list: 'send_sync_list',
|
||||||
handle_sync_list: 'handle_sync_list',
|
handle_sync_list: 'handle_sync_list',
|
||||||
},
|
},
|
||||||
|
taskbar: {
|
||||||
|
setTaskbarThumbnailClip: 'setTaskbarThumbnailClip',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const item of Object.keys(names)) {
|
for (const item of Object.keys(names)) {
|
||||||
|
@ -80,3 +83,4 @@ export const player = names.player
|
||||||
export const list = names.list
|
export const list = names.list
|
||||||
export const download = names.download
|
export const download = names.download
|
||||||
export const sync = names.sync
|
export const sync = names.sync
|
||||||
|
export const taskbar = names.taskbar
|
||||||
|
|
|
@ -310,3 +310,16 @@ export const hotKeySetConfig = (config) => {
|
||||||
export const hotKeyGetStatus = () => {
|
export const hotKeyGetStatus = () => {
|
||||||
return rendererInvoke(NAMES.hotKey.status)
|
return rendererInvoke(NAMES.hotKey.status)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const onTaskbarThumbarClick = callback => {
|
||||||
|
rendererOn(NAMES.mainWindow.taskbar_on_thumbar_button_click, callback)
|
||||||
|
return () => {
|
||||||
|
rendererOff(callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export const setTaskbarThumbnailClip = (clip) => {
|
||||||
|
return rendererInvoke(NAMES.mainWindow.taskbar_set_thumbnail_clip, clip)
|
||||||
|
}
|
||||||
|
export const setTaskbarThumbarButtons = (buttons) => {
|
||||||
|
rendererSend(NAMES.mainWindow.taskbar_set_thumbar_buttons, buttons)
|
||||||
|
}
|
||||||
|
|
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 781 B |
After Width: | Height: | Size: 943 B |
After Width: | Height: | Size: 731 B |
After Width: | Height: | Size: 729 B |
After Width: | Height: | Size: 491 B |
After Width: | Height: | Size: 675 B |
After Width: | Height: | Size: 762 B |