ElyPrism ce51da9150
build(version): bump 4.30.0 (#102)
* chore(deps): bump actions/checkout from 4 to 6

Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* Squashed commit of the following:

commit f73cbbeec37d40383e2b7d411e34048146776345
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Sun Feb 1 12:47:57 2026 +0000

    chore(deps): bump actions/download-artifact from 4 to 7

    Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4 to 7.
    - [Release notes](https://github.com/actions/download-artifact/releases)
    - [Commits](https://github.com/actions/download-artifact/compare/v4...v7)

    ---
    updated-dependencies:
    - dependency-name: actions/download-artifact
      dependency-version: '7'
      dependency-type: direct:production
      update-type: version-update:semver-major
    ...

    Signed-off-by: dependabot[bot] <support@github.com>

* Squashed commit of the following:

commit 4da2d5f3600f52c7087ea350e3ec87a3c7cac535
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Sun Feb 1 12:48:00 2026 +0000

    chore(deps): bump actions/github-script from 7 to 8

    Bumps [actions/github-script](https://github.com/actions/github-script) from 7 to 8.
    - [Release notes](https://github.com/actions/github-script/releases)
    - [Commits](https://github.com/actions/github-script/compare/v7...v8)

    ---
    updated-dependencies:
    - dependency-name: actions/github-script
      dependency-version: '8'
      dependency-type: direct:production
      update-type: version-update:semver-major
    ...

    Signed-off-by: dependabot[bot] <support@github.com>

* Squashed commit of the following:

commit 9e65b176252a554decf5574ca6a3463838a7a32f
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Sun Feb 1 12:47:49 2026 +0000

    chore(deps): bump actions/setup-node from 4 to 6

    Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4 to 6.
    - [Release notes](https://github.com/actions/setup-node/releases)
    - [Commits](https://github.com/actions/setup-node/compare/v4...v6)

    ---
    updated-dependencies:
    - dependency-name: actions/setup-node
      dependency-version: '6'
      dependency-type: direct:production
      update-type: version-update:semver-major
    ...

    Signed-off-by: dependabot[bot] <support@github.com>

* Squashed commit of the following:

commit a060f3c4cc5c3a4baf9c4827163acde1589ef26d
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Sun Feb 1 12:47:53 2026 +0000

    chore(deps): bump actions/upload-artifact from 4 to 6

    Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 6.
    - [Release notes](https://github.com/actions/upload-artifact/releases)
    - [Commits](https://github.com/actions/upload-artifact/compare/v4...v6)

    ---
    updated-dependencies:
    - dependency-name: actions/upload-artifact
      dependency-version: '6'
      dependency-type: direct:production
      update-type: version-update:semver-major
    ...

    Signed-off-by: dependabot[bot] <support@github.com>

* build(version): bump 4.30.0

* refactor: QR login and voice upload pages with improved UI and error handling

- Enhanced styling for better user experience on qrlogin-nocookie.html and qrlogin.html
- Added loading indicators and improved status messages during QR code login process
- Updated error handling for login status retrieval
- Refactored unblock_test.html for better layout and user interaction
- Improved voice upload page with a more intuitive design and better feedback for file uploads
- Added loading state management for voice list retrieval
- Enhanced accessibility and usability across all modified pages

* fix: Potential fix for code scanning alert no. 6: DOM text reinterpreted as HTML

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

* Potential fix for code scanning alert no. 15: DOM text reinterpreted as HTML

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

* build: update utils

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-02-09 23:33:26 +08:00

327 lines
7.6 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>更新头像</title>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
min-height: 100vh;
background: #f5f5f5;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
}
.container {
background: white;
border-radius: 12px;
padding: 40px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
max-width: 400px;
width: 100%;
text-align: center;
}
h1 {
font-size: 24px;
font-weight: 600;
color: #333;
margin-bottom: 8px;
}
.subtitle {
font-size: 14px;
color: #666;
margin-bottom: 32px;
}
.avatar-wrapper {
position: relative;
width: 160px;
height: 160px;
margin: 0 auto 32px;
}
.avatar {
width: 100%;
height: 100%;
border-radius: 50%;
object-fit: cover;
border: 3px solid #fff;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.avatar-wrapper.loading .avatar {
opacity: 0.5;
}
.loading-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 50%;
background: rgba(255, 255, 255, 0.9);
display: flex;
align-items: center;
justify-content: center;
opacity: 0;
transition: opacity 0.2s ease;
}
.avatar-wrapper.loading .loading-overlay {
opacity: 1;
}
.spinner {
width: 40px;
height: 40px;
border: 3px solid #e0e0e0;
border-top-color: #333;
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
.upload-btn {
display: inline-block;
position: relative;
padding: 12px 28px;
background: #333;
color: white;
font-size: 15px;
font-weight: 500;
border-radius: 6px;
cursor: pointer;
transition: background 0.2s ease;
border: none;
}
.upload-btn:hover {
background: #555;
}
.upload-btn input[type="file"] {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
cursor: pointer;
}
.login-link {
display: block;
margin-top: 24px;
color: #666;
font-size: 14px;
text-decoration: none;
}
.login-link:hover {
color: #333;
text-decoration: underline;
}
.toast {
position: fixed;
bottom: 24px;
left: 50%;
transform: translateX(-50%) translateY(100px);
padding: 12px 20px;
border-radius: 6px;
font-size: 14px;
font-weight: 500;
color: white;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
opacity: 0;
transition: all 0.3s ease;
z-index: 1000;
max-width: 90%;
text-align: center;
}
.toast.show {
transform: translateX(-50%) translateY(0);
opacity: 1;
}
.toast.success {
background: #10b981;
}
.toast.error {
background: #ef4444;
}
.toast.info {
background: #3b82f6;
}
.hint {
margin-top: 20px;
font-size: 12px;
color: #999;
}
</style>
</head>
<body>
<div class="container">
<h1>更新头像</h1>
<p class="subtitle">选择一张图片作为您的新头像</p>
<div class="avatar-wrapper" id="avatarWrapper">
<img id="avatar" class="avatar" src="" alt="头像" />
<div class="loading-overlay">
<div class="spinner"></div>
</div>
</div>
<label class="upload-btn">
选择图片
<input id="file" type="file" accept="image/*" />
</label>
<a href="/qrlogin-nocookie.html" class="login-link">
还没有登录?点击登录
</a>
<p class="hint">支持 JPG、PNG 格式,建议尺寸 200x200</p>
</div>
<div id="toast" class="toast"></div>
<script src="https://fastly.jsdelivr.net/npm/axios@0.26.1/dist/axios.min.js"></script>
<script>
main()
async function main() {
const fileInput = document.querySelector('input[type="file"]');
const avatarWrapper = document.getElementById('avatarWrapper');
fileInput.addEventListener('change', function(e) {
const file = this.files[0];
if (file) {
upload(file);
}
}, false);
try {
showToast('正在加载头像...', 'info');
avatarWrapper.classList.add('loading');
const res = await axios({
url: `/user/detail?uid=32953014&timestamp=${Date.now()}`,
withCredentials: true
});
document.querySelector('#avatar').src = res.data.profile.avatarUrl;
hideToast();
} catch (error) {
hideToast();
showToast('加载头像失败,请刷新页面重试', 'error');
console.error('加载头像失败:', error);
} finally {
avatarWrapper.classList.remove('loading');
}
}
async function upload(file) {
const avatarWrapper = document.getElementById('avatarWrapper');
if (!file.type.startsWith('image/')) {
showToast('请选择图片文件', 'error');
return;
}
try {
showToast('正在上传头像...', 'info');
avatarWrapper.classList.add('loading');
var formData = new FormData();
formData.append('imgFile', file);
const imgSize = await getImgSize(file);
const res = await axios({
method: 'post',
url: `/avatar/upload?cookie=${localStorage.getItem('cookie')}&imgSize=${imgSize.width}&imgX=0&imgY=0&timestamp=${Date.now()}`,
headers: {
'Content-Type': 'multipart/form-data',
},
data: formData,
});
document.querySelector('#avatar').src = res.data.data.url;
showToast('头像更新成功', 'success');
} catch (error) {
console.error('上传失败:', error);
const errorMsg = error.response?.data?.message || error.message || '上传失败请重试';
showToast(errorMsg, 'error');
} finally {
avatarWrapper.classList.remove('loading');
}
}
function getImgSize(file) {
return new Promise((resolve, reject) => {
let reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function(theFile) {
let image = new Image();
image.src = theFile.target.result;
image.onload = function() {
resolve({
width: this.width,
height: this.height,
});
};
image.onerror = function() {
reject(new Error('图片加载失败'));
};
};
reader.onerror = function() {
reject(new Error('文件读取失败'));
};
});
}
function showToast(message, type = 'info') {
const toast = document.getElementById('toast');
toast.textContent = message;
toast.className = `toast ${type}`;
requestAnimationFrame(() => {
toast.classList.add('show');
});
setTimeout(() => {
toast.classList.remove('show');
}, 3000);
}
function hideToast() {
const toast = document.getElementById('toast');
toast.classList.remove('show');
}
</script>
</body>
</html>