Skip to content

Commit

Permalink
Sync 0.2.1
Browse files Browse the repository at this point in the history
  • Loading branch information
YanJi314 committed Oct 1, 2024
1 parent fb0a49c commit 5a6cbd9
Show file tree
Hide file tree
Showing 9 changed files with 150 additions and 34 deletions.
4 changes: 2 additions & 2 deletions src/frontend/assets/components/ContextMenu.css
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@
border-top: solid 1px rgb(0 0 0 / .05);
}
.context-menu .disabled {
color: rgb(0 0 0 / .5) !important;
color: black !important;
background-color: transparent !important;
opacity: 1 !important;
opacity: .5 !important;
}

.context-menu .sub {
Expand Down
2 changes: 0 additions & 2 deletions src/frontend/assets/components/SimAP.css
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ body.albumScale:not(.playing) .controls #album{transform:scale(.95);}
.playing .controls .buttons>.play>i:first-child,.playing .bottom .center>.play>i:first-child{opacity:0;transform:scale(.4);}
.playing .controls .buttons>.play>i:last-child,.playing .bottom .center>.play>i:last-child{opacity:1;transform:none;}
.controls .buttons>.play i:first-child,.bottom .center>.play i:first-child{padding-left:3.5px;}
.playBtnColor .controls .buttons{color:var(--SimAPTheme);}
.playBtnColor .bottom .center>.play{color:#1E9FFF;}
/* 音量控制 */
.volume .controls .buttons>div{width:0;opacity:0!important;}
.volume .controls .buttons>.volBtn{width:180px;color:rgba(0,0,0,.7);background:rgba(0,0,0,.05)!important;transform:none!important;opacity:1!important;mask:unset;border-radius:100px;}
Expand Down
1 change: 1 addition & 0 deletions src/frontend/assets/components/SimAP.js
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ const SimAPControls = {
if (isManual) SleepMode.checkManualOperation();
if (document.body.classList.contains("musicLoading")) return;
const audio = document.getElementById("audio");
if (!audio || !audio.src) return;
const isPlay = audio.paused;
document.body.classList[isPlay ? "add" : "remove"]("playing");
SimAPControls.loadAudioState();
Expand Down
6 changes: 3 additions & 3 deletions src/frontend/assets/components/shutdown.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@
<script>
// 读取配置信息
const operationType = config.getItem("sleepModeOperation");
operation.innerText = {shutdown: "关机", sleep: "休眠"}[operationType];
operation.textContent = {shutdown: "关机", sleep: "休眠"}[operationType];
const intervalId = setInterval(() => {
timer.innerText --;
if (timer.innerText == "0") {
timer.textContent --;
if (timer.textContent == "0") {
clearInterval(intervalId);
const {ipcRenderer} = require("electron");
ipcRenderer.invoke("cmd", `shutdown /${{shutdown: "s /hybrid /f /t 0", sleep: "h"}[operationType]}`);
Expand Down
2 changes: 1 addition & 1 deletion src/frontend/assets/components/webview.html
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
progressBar.classList.add("finished");
});
webview.addEventListener("did-fail-load", () => {
webview.loadURL("data:text/html;base64,PGh0bWw+CiAgICA8aGVhZD4KICAgICAgICA8bWV0YSBjaGFyc2V0PSJ1dGYtOCI+CiAgICAgICAgPHRpdGxlPumUmeivrzwvdGl0bGU+CiAgICA8L2hlYWQ+CiAgICA8Ym9keT4KICAgICAgICA8c3R5bGU+CiAgICAgICAgICAgIGJvZHl7dGV4dC1hbGlnbjpjZW50ZXI7YmFja2dyb3VuZDojRjlGOUZCO30KICAgICAgICAgICAgaDF7bWFyZ2luOmNhbGMoNTB2aCAtIDEwMHB4KSAwIDAgMDt9CiAgICAgICAgICAgIHB7bWFyZ2luOjEwcHggMCAwIDA7Zm9udC1zaXplOjEuMnJlbTt9CiAgICAgICAgICAgIGRpdntvcGFjaXR5Oi44O21hcmdpbi10b3A6Y2FsYyg1MHZoIC0gNTBweCk7fQogICAgICAgIDwvc3R5bGU+CiAgICAgICAgPGgxPuWHuueOsOmUmeivrzwvaDE+CiAgICAgICAgPHA+5b6I5oqx5q2J77yM6aG16Z2i5Yqg6L295aSx6LSlPC9wPgogICAgICAgIDxkaXY+U2ltTXVzaWM8L2Rpdj4KICAgIDwvYm9keT4KPC9odG1sPg==");
//webview.loadURL("data:text/html;base64,PGh0bWw+CiAgICA8aGVhZD4KICAgICAgICA8bWV0YSBjaGFyc2V0PSJ1dGYtOCI+CiAgICAgICAgPHRpdGxlPumUmeivrzwvdGl0bGU+CiAgICA8L2hlYWQ+CiAgICA8Ym9keT4KICAgICAgICA8c3R5bGU+CiAgICAgICAgICAgIGJvZHl7dGV4dC1hbGlnbjpjZW50ZXI7YmFja2dyb3VuZDojRjlGOUZCO30KICAgICAgICAgICAgaDF7bWFyZ2luOmNhbGMoNTB2aCAtIDEwMHB4KSAwIDAgMDt9CiAgICAgICAgICAgIHB7bWFyZ2luOjEwcHggMCAwIDA7Zm9udC1zaXplOjEuMnJlbTt9CiAgICAgICAgICAgIGRpdntvcGFjaXR5Oi44O21hcmdpbi10b3A6Y2FsYyg1MHZoIC0gNTBweCk7fQogICAgICAgIDwvc3R5bGU+CiAgICAgICAgPGgxPuWHuueOsOmUmeivrzwvaDE+CiAgICAgICAgPHA+5b6I5oqx5q2J77yM6aG16Z2i5Yqg6L295aSx6LSlPC9wPgogICAgICAgIDxkaXY+U2ltTXVzaWM8L2Rpdj4KICAgIDwvYm9keT4KPC9odG1sPg==");
});
function cancelDialog() {
ipcRenderer.invoke("dialogCancel", queryParams.get("parent"));
Expand Down
6 changes: 4 additions & 2 deletions src/frontend/assets/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,9 @@ body:not(.miniModeStatus) .bottom .info .musicInfoBottom>div #miniModeStatus{tra
.bottom .center>div.play{width:55px;height:55px;}
.bottom .volBtnBottom{width:150px;position:absolute;top:5px;bottom:0;right:30px;display:flex;align-items:center;}
.bottom .volBtnBottom>div{opacity:.7;margin-right:5px;min-width:40px;height:40px;}

.playBtnColor .bottom .center>.play{background:#1e9fff;color:white;font-size:1.6em;width:50px;height:50px;margin: 0 5px;}
.playBtnColor .bottom .center>.play:hover,.playBtnColor .bottom .center>.play:active{filter:brightness(.95);}
.playBtnColor .bottom .center>div{opacity:.5;}


/* 主窗体 - 播放内页 */
Expand All @@ -269,7 +271,7 @@ body:not(.miniModeStatus) .bottom .info .musicInfoBottom>div #miniModeStatus{tra
.darkPlayer #playPage #background{opacity:.35;}
.darkPlayer #playPage #background canvas{opacity:.5;}
.darkPlayer.playerShown header i{color:rgba(255,255,255,.8);}
.darkPlayer .controls #album,.list>div>img{background:rgba(0,0,0,.1);}
.darkPlayer .controls #album,.darkPlayer .list>div>img{background:rgba(0,0,0,.1);}
.darkPlayer .controls .infoBar i{background:rgba(255,255,255,.025);color:rgba(255,255,255,.6);}
.darkPlayer .controls .infoBar i:hover,.darkPlayer .controls .infoBar i:active{background:rgba(255,255,255,.05);color:rgba(255,255,255,.8);}
.darkPlayer .controls .buttons>div:hover,.darkPlayer .controls .buttons>div:active{background:rgba(255,255,255,.05);}
Expand Down
152 changes: 130 additions & 22 deletions src/frontend/assets/main.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
SimMusicVersion = "0.2.0";
SimMusicVersion = "0.2.1";


// 窗口处理
Expand Down Expand Up @@ -160,17 +160,24 @@ const ExtensionRuntime = {
div.classList.add("block");
div.innerHTML = `
<section>
<div>${SimMusicTools.escapeHtml(extData[packageId].extName)}</div>
<div>${SimMusicTools.escapeHtml(extData[packageId].extName)}${extData[packageId].isDev ? ` <badge><i>&#xEBAD;</i> 由清单文件加载的开发扩展</badge>` : ""}</div>
<span>
<i>&#xEE59;</i> 扩展包名: ${SimMusicTools.escapeHtml(packageId)}<br>
<i>&#xEE51;</i> 扩展版本: ${SimMusicTools.escapeHtml(extData[packageId].version)}<br>
${extError ? `<i>&#xEB97;</i> ${extError}` : ""}
${extError ? `<i>&#xEB97;</i> ${SimMusicTools.escapeHtml(extError)}<br>` : ""}
</span>
</section>
<div class="${permData[packageId]?.removeSidebar ? "" : `on `}perm permSidebar">在导航栏显示<span class="toggle"></span></div>
<div class="${permData[packageId]?.removeSidebar ? "" : `on `}perm permSidebar">允许显示歌单<span class="toggle"></span></div>
<button class="sub"${packageId == "file" ? " disabled" : ""}>卸载</button>`;
div.querySelector("button").onclick = () => {
this.uninstall(packageId);
if (!extData[packageId].isDev) this.uninstall(packageId);
else {
confirm("确实要卸载开发扩展吗?", () => {
config.setItem("devExt", null);
alert("扩展已成功卸载,按「确定」重载此应用生效。", () => { ipcRenderer.invoke("restart"); });
});
}
};
const togglePerm = (name, className) => {
document.getElementById("extReloadTip").hidden = false;
Expand Down Expand Up @@ -230,12 +237,18 @@ const ExtensionRuntime = {
code: code,
};
config.setItem("ext", extData);
alert("扩展已成功安装,按「确定」重载此应用生效。", () => {
ipcRenderer.invoke("restart");
});
alert("扩展已成功安装,按「确定」重载此应用生效。", () => { ipcRenderer.invoke("restart"); });
} catch (err) {
console.warn(err);
alert("扩展包已损坏、无法读取或存在未知错误。");
if (file.path.endsWith("manifest.json") && config.getItem("devMode")) {
try {
config.setItem("devExt", file.path);
alert("已从清单文件加载此扩展,按「确定」重载此应用生效。", () => { ipcRenderer.invoke("restart"); });
} catch {
alert("扩展清单文件损坏或无法读取。");
}
}
else alert("扩展包已损坏、无法读取或存在未知错误。");
}
});
},
Expand All @@ -244,13 +257,38 @@ const ExtensionRuntime = {
const extData = config.getItem("ext");
delete extData[packageId];
config.setItem("ext", extData);
alert("扩展已成功卸载,按「确定」重载此应用生效。", () => {
ipcRenderer.invoke("restart");
});
alert("扩展已成功卸载,按「确定」重载此应用生效。", () => { ipcRenderer.invoke("restart"); });
});
},
async getExtData() {
const extData = config.getItem("ext");
if (config.getItem("devExt")) {
try {
const json = fs.readFileSync(config.getItem("devExt"));
const manifest = JSON.parse(json);
if (!manifest.packageId || !manifest.version || !manifest.extName) throw("");
const extPath = path.dirname(config.getItem("devExt"));
let code = "";
manifest.entries.forEach(entry => {
code += fs.readFileSync(path.join(extPath, entry));
});
extData[manifest.packageId] = {
code,
extName: manifest.extName,
uiName: manifest.uiName ?? manifest.extName,
version: manifest.version,
isDev: true,
}
} catch {
extData["dev-error"] = {
code: "throw('清单文件损坏')",
extName: "dev-error",
uiName: "dev-error",
version: "dev-error",
isDev: true,
}
}
}
extData["file"] = {
code: await (await fetch("assets/components/LocalFolderExtension.js")).text(),
uiName: "本地",
Expand All @@ -264,6 +302,37 @@ ExtensionRuntime.init();



// 扩展支持函数
ExtensionFunctions = {
insertStyle(css) {
const style = document.createElement("style");
style.innerHTML = css;
document.documentElement.appendChild(style);
},
insertNavigationItem(options) {
if (document.getElementById(options.pageId)) return;
const navbarDiv = document.createElement("div");
navbarDiv.dataset.pageId = options.pageId;
navbarDiv.innerHTML = `<i>&#x${options.icon};</i> ${SimMusicTools.escapeHtml(options.text)}`;
navbarDiv.onclick = () => {switchRightPage(options.pageId);};
if (options.appendBefore) {
let appendBeforeElement;
document.querySelectorAll(".left>div>div[data-page-id]").forEach(div => {
if (div.dataset.pageId == options.appendBefore) appendBeforeElement = div;
});
document.querySelector(".left>div").insertBefore(navbarDiv, appendBeforeElement);
} else document.querySelector(".left>div").appendChild(navbarDiv);
const pageDiv = document.createElement("div");
pageDiv.id = options.pageId;
pageDiv.hidden = true;
document.querySelector(".right").appendChild(pageDiv);
return {navbarDiv, pageDiv};
},
};





// 左侧栏大小调整
document.getElementById("leftBarResizer").addEventListener("mousedown", e => {
Expand Down Expand Up @@ -1010,6 +1079,7 @@ const PlayerController = {
document.body.appendChild(audio);
loadVolumeUi();
document.title = "SimMusic";
eqAudioContext = eqSource = null;
this.loadMusicListActive();
},
// 渲染歌单界面播放中歌曲
Expand Down Expand Up @@ -1160,7 +1230,7 @@ SleepMode = {
const offset = currentTime - this.status[0];
document.body.classList.add("sleepMode");
const indicatorTime = Math.round(this.status[1] * 60 - offset / 1000);
document.querySelector(".controls .infoBar i").innerText = indicatorTime < 0 ? ("+" + SimMusicTools.formatTime(0 - indicatorTime)) : SimMusicTools.formatTime(indicatorTime);
document.querySelector(".controls .infoBar i").textContent = indicatorTime < 0 ? ("+" + SimMusicTools.formatTime(0 - indicatorTime)) : SimMusicTools.formatTime(indicatorTime);
if (offset / 1000 / 60 > this.status[1]) this.endTime();
},
endTime() {
Expand Down Expand Up @@ -1203,18 +1273,17 @@ SleepMode = {
function openEqConfig() {
modalWindow("modal-eq.html", 300);
}
let eqAudioContext;
let eqSsource;
let eqAudioContext, eqSource;
let eqCurrentFilters = [];
function applyEq() {
const data = config.getItem("eqProfile") == "basic" ? config.getItem("eqConfBasic") : config.getItem("eqConfPro");
try {
const audioElement = document.getElementById("audio");
if (!eqAudioContext) eqAudioContext = new AudioContext();
if (!eqSsource) eqSsource = eqAudioContext.createMediaElementSource(audioElement);
if (!eqSource) eqSource = eqAudioContext.createMediaElementSource(audioElement);
eqCurrentFilters.forEach(filter => {
try {
eqSsource.disconnect(filter);
eqSource.disconnect(filter);
filter.disconnect(eqAudioContext.destination);
} catch {}
});
Expand All @@ -1226,7 +1295,7 @@ function applyEq() {
filter.Q.value = item.Q;
return filter;
});
let lastNode = eqSsource;
let lastNode = eqSource;
filters.forEach(filter => {
lastNode.connect(filter);
lastNode = filter;
Expand Down Expand Up @@ -1535,11 +1604,12 @@ const SettingsPage = {
{type: "title", text: "通用配置"},
{type: "boolean", text: "不驻留后台进程", description: "关闭主界面时停止播放并完全退出应用。", configItem: "disableBackground"},
{type: "boolean", text: "注册系统菜单", badges: ["experimental"], description: "开启后,您可以在音频文件右键的「打开方式」菜单中选择 SimMusic 进行播放。在移动 SimMusic 程序目录或移除 SimMusic 前,您需要先关闭此选项。", configItem: "systemMenu"},
{type: "select", text: "更新下载源", description: "在境内连接 Github 官方源可能导致下载速度极慢或下载失败。", options: [["", "Github 官方源"], ["https://ghp.ci/", "GHProxy 镜像"], ["https://gh.wwvw.top/", "CloudFlare"]], configItem: "updatePrefix"},
{type: "select", text: "更新下载源", description: "在境内连接 GitHub 官方源可能导致下载速度极慢或下载失败。", options: [["", "GitHub 官方源"], ["https://ghp.ci/", "GHProxy 镜像"], ["https://gh.wwvw.top/", "CloudFlare"]], configItem: "updatePrefix"},
{type: "title", text: "音频扫描"},
{type: "input", text: "本地音频格式", description: "扫描本地音乐与导入本地文件时识别的音频文件扩展名,以空格分隔。", configItem: "musicFormats"},
{type: "title", text: "歌单界面"},
{type: "boolean", text: "显示「曲目定位」按钮", configItem: "showLocator"},
{type: "boolean", text: "对播放按钮应用主题色", configItem: "playBtnColor"},
{type: "boolean", text: "启用主题图片", description: "在 SimMusic 主界面显示主题图片。", configItem: "themeImage"},
{type: "select", text: "选择主题图片", options: [["cover", "曲目封面"], ["local", "本地文件"]], configItem: "themeImageType", attachTo: "themeImage"},
{type: "boolean", text: "图片模糊效果", configItem: "themeImageBlur", attachTo: "themeImage"},
Expand All @@ -1548,7 +1618,6 @@ const SettingsPage = {
{type: "boolean", text: "背景动态混色", description: "关闭后可减少播放页对硬件资源的占用。", configItem: "backgroundBlur"},
{type: "boolean", text: "3D 特效", badges: ["experimental"], description: "在播放页的歌曲信息、播放列表与歌词视图使用 3D 视觉效果。", configItem: "3dEffect"},
{type: "boolean", text: "专辑封面缩放", description: "在按下「播放」或「暂停」时对播放页专辑封面使用缩放动效。", configItem: "albumScale"},
{type: "boolean", text: "对播放按钮应用主题色", configItem: "playBtnColor"},
{type: "title", text: "播放控制"},
{type: "boolean", text: "快速重播", description: "在曲目即将结束时按「快退」按钮以回到当前曲目的开头。", configItem: "fastPlayback"},
{type: "boolean", text: "音频淡入淡出", description: "在按下「播放」或「暂停」时对音频的输出音量使用渐变效果。", configItem: "audioFade"},
Expand Down Expand Up @@ -1667,6 +1736,7 @@ const SettingsPage = {
SettingsPage.loadElementHeight();
SettingsPage.loadElementFoldStatus();
});
initInputMenu();
},
loadElementHeight() {
document.querySelectorAll("#settingsContainer>div[data-attach-to]").forEach(div => {
Expand All @@ -1682,6 +1752,44 @@ const SettingsPage = {
}
window.addEventListener("resize", SettingsPage.loadElementHeight);



// 输入框右键菜单
function initInputMenu() {
document.querySelectorAll("input").forEach(input => {
if (!input.oncontextmenu && !["date", "time", "file", "color", "button", "checkbox"].includes(input.type)) input.oncontextmenu = e => {
const isFocused = getSelection().toString().trim() && (getSelection().anchorNode.contains(input) || getSelection().anchorNode == input);
new ContextMenu([
{
label: "全选",
icon: "F1FF",
click() { input.select(); },
},
{
label: "复制",
icon: "ECD5",
click() { document.execCommand("copy"); },
disabled: !isFocused,
},
{
label: "剪切",
icon: "F0C1",
click() { document.execCommand("cut"); },
disabled: !isFocused,
},
{
label: "粘贴",
click() { document.execCommand("paste"); },
icon: "EB91",
},
]).popup([e.clientX, e.clientY]);
}
});
}
initInputMenu();



// 桌面歌词
function updateDesktopLyricsConfig() {
ipcRenderer.invoke("updateDesktopLyricsConfig", config.getItem("desktopLyricsProtection"));
Expand Down Expand Up @@ -1725,11 +1833,11 @@ fetch(`https://api.github.com/repos/${ghRepo}/releases/latest`)
if (json.name != SimMusicVersion) {
document.querySelector(".leftBar>div[data-page-id='updatePage']").hidden = false;
document.getElementById("updateInfo").innerHTML = marked.parse(json.body?.split("<!-- CL START -->")[1]?.split("<!-- CL END -->")[0] ?? "更新信息获取失败");
document.getElementById("updateVersion").innerText = `版本 ${json.name} · 发布于 ${json.published_at.substring(0, 10)}`;
document.getElementById("updateVersion").textContent = `版本 ${json.name} · 发布于 ${json.published_at.substring(0, 10)}`;
if (json?.assets[0] && json?.assets[0]?.name == "auto-update-package") updateUrl = json?.assets[0]?.browser_download_url;
}
});
function startUpdate() {
if (!updateUrl) return document.getElementById("updateInfoBtn").click();
modalWindow("modal-update.html?downUrl=" + `${config.getItem("updatePrefix")}${updateUrl}`, 160);
}
}
2 changes: 1 addition & 1 deletion src/frontend/main.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
<span id="extBars"></span>
<section class="title"><span>歌单</span><i onclick="MusicList.add()">&#xF4B2;</i></section>
<section id="musicLists"></section>
<section class="title"><span>其他</span></section>
<section class="title"><span>功能</span></section>
<div data-page-id="searchPage" onclick="Search.switchSearch()" id="searchBtn"><i>&#xF0D1;</i> 搜索</div>
<div data-page-id="downloadPage" onclick="switchRightPage('downloadPage')" hidden><i>&#xEC5A;</i> 下载</div>
<div data-page-id="extensionPage" onclick="switchRightPage('extensionPage')"><i>&#xF450;</i> 扩展</div>
Expand Down
9 changes: 8 additions & 1 deletion src/main.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

// © 2020 - 2024 Simsv Studio

const {app, BrowserWindow, ipcMain, dialog, nativeImage, Tray, Menu, screen, session, webContents} = require("electron");
const {app, BrowserWindow, ipcMain, dialog, nativeImage, Tray, Menu, screen, session, webContents, desktopCapturer} = require("electron");
const {exec} = require("child_process");
const path = require("path");
const fs = require("fs");
Expand Down Expand Up @@ -85,6 +85,11 @@ app.whenReady().then(() => {
showMainWin();
}
});
session.defaultSession.setDisplayMediaRequestHandler((request, callback) => {
desktopCapturer.getSources({ types: ["screen"] }).then((sources) => {
callback({ video: sources[0], audio: "loopback" })
});
});
});
ipcMain.handle("mainWinLoaded", () => {
if (isMainWinLoaded) return [];
Expand Down Expand Up @@ -156,6 +161,8 @@ ipcMain.handle("webview", (_event, url, parent, dialogId, width, height, showFin
modal: true,
width: width ?? 600,
height: height ?? 500,
minWidth: 600,
minHeight: 500,
frame: false,
resizable: true,
show: false,
Expand Down

0 comments on commit 5a6cbd9

Please sign in to comment.