🎉 first commit
107
app/components/upage/Brand.tsx
Normal file
@@ -0,0 +1,107 @@
|
||||
import logo from './icons/logo.svg?raw';
|
||||
|
||||
export function UPageBrand() {
|
||||
const styles = `
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; transform: translateY(10px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
|
||||
@keyframes ripple {
|
||||
to {
|
||||
transform: scale(4);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.upage-floating-bar {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 8px 12px;
|
||||
background-color: rgba(255, 255, 255, 0.9);
|
||||
border-radius: 30px;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
||||
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
z-index: 9999;
|
||||
transition: all 0.3s ease;
|
||||
animation: fadeIn 0.5s ease-in-out;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.upage-floating-bar:hover {
|
||||
transform: scale(1.05);
|
||||
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.upage-logo {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-right: 8px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.upage-text {
|
||||
margin: 0;
|
||||
font-weight: 500;
|
||||
font-size: 12px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.upage-ripple {
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
background-color: rgba(0, 62, 183, 0.2);
|
||||
transform: scale(0);
|
||||
animation: ripple 0.6s linear;
|
||||
pointer-events: none;
|
||||
}
|
||||
`;
|
||||
|
||||
const script = `
|
||||
(function() {
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// 品牌悬浮框点击事件
|
||||
var floatingBar = document.querySelector('.upage-floating-bar');
|
||||
if (floatingBar) {
|
||||
floatingBar.addEventListener('click', function(e) {
|
||||
var ripple = document.createElement('span');
|
||||
ripple.classList.add('upage-ripple');
|
||||
|
||||
var rect = floatingBar.getBoundingClientRect();
|
||||
var x = e.clientX - rect.left;
|
||||
var y = e.clientY - rect.top;
|
||||
|
||||
ripple.style.left = x + 'px';
|
||||
ripple.style.top = y + 'px';
|
||||
|
||||
floatingBar.appendChild(ripple);
|
||||
|
||||
setTimeout(function() {
|
||||
ripple.remove();
|
||||
}, 600);
|
||||
|
||||
window.open('https://upage.ai', '_blank');
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
||||
`;
|
||||
|
||||
return (
|
||||
<>
|
||||
<style dangerouslySetInnerHTML={{ __html: styles }} />
|
||||
<script dangerouslySetInnerHTML={{ __html: script }} />
|
||||
<div className="upage-floating-bar">
|
||||
<div className="upage-logo" dangerouslySetInnerHTML={{ __html: logo }}></div>
|
||||
<span className="upage-text">使用 UPage 构建</span>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
11
app/components/upage/Index.tsx
Normal file
@@ -0,0 +1,11 @@
|
||||
import { UPageBrand } from './Brand';
|
||||
import { UPageShare } from './Share';
|
||||
|
||||
export function UPageIndex() {
|
||||
return (
|
||||
<>
|
||||
<UPageShare />
|
||||
<UPageBrand />
|
||||
</>
|
||||
);
|
||||
}
|
||||
605
app/components/upage/Share.tsx
Normal file
@@ -0,0 +1,605 @@
|
||||
import qrcode from 'node_modules/qrcode/build/qrcode?raw';
|
||||
import { getLocalStorage } from '~/lib/persistence';
|
||||
import closeIcon from './icons/close.svg?raw';
|
||||
import copyIcon from './icons/copy.svg?raw';
|
||||
import shareIcon from './icons/share.svg?raw';
|
||||
import twitterIcon from './icons/twitter.svg?raw';
|
||||
import wechatIcon from './icons/wechat.svg?raw';
|
||||
import weiboIcon from './icons/weibo.svg?raw';
|
||||
|
||||
export function UPageShare() {
|
||||
const recommend = getLocalStorage('recommend');
|
||||
|
||||
const styles = `
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; transform: translateY(10px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
|
||||
@keyframes scaleIn {
|
||||
from { opacity: 0; transform: scale(0.9); }
|
||||
to { opacity: 1; transform: scale(1); }
|
||||
}
|
||||
|
||||
@keyframes ripple {
|
||||
to {
|
||||
transform: scale(4);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* 分享按钮样式 */
|
||||
.upage-share-btn {
|
||||
position: fixed;
|
||||
bottom: 70px;
|
||||
right: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 8px 12px;
|
||||
background-color: rgba(255, 255, 255, 0.9);
|
||||
border-radius: 30px;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
||||
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
z-index: 9999;
|
||||
transition: all 0.3s ease;
|
||||
animation: fadeIn 0.5s ease-in-out;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.upage-share-btn:hover {
|
||||
transform: scale(1.05);
|
||||
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.upage-share-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-right: 8px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.upage-ripple {
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
background-color: rgba(0, 62, 183, 0.2);
|
||||
transform: scale(0);
|
||||
animation: ripple 0.6s linear;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.upage-text {
|
||||
margin: 0;
|
||||
font-weight: 500;
|
||||
font-size: 12px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* 分享对话框样式 */
|
||||
.upage-share-modal {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 10000;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: opacity 0.3s ease, visibility 0.3s ease;
|
||||
}
|
||||
|
||||
.upage-share-modal.active {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.upage-share-content {
|
||||
width: 90%;
|
||||
max-width: 500px;
|
||||
background-color: white;
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
|
||||
transform: scale(0.9);
|
||||
opacity: 0;
|
||||
transition: transform 0.3s ease, opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.upage-share-modal.active .upage-share-content {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.upage-share-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.upage-share-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.upage-share-close {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s ease;
|
||||
border: none;
|
||||
outline: none;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.upage-share-close:hover {
|
||||
background-color: #e0e0e0;
|
||||
}
|
||||
|
||||
.upage-share-preview {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
border-radius: 8px;
|
||||
background-color: #f5f5f5;
|
||||
margin-bottom: 16px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.upage-share-preview-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.upage-share-options {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 16px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.upage-share-option {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s ease;
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
.upage-share-option:hover {
|
||||
transform: translateY(-3px);
|
||||
}
|
||||
|
||||
.upage-share-option-icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
background-color: #f0f0f0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.upage-share-option-icon svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.upage-share-option-name {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.upage-share-success {
|
||||
position: fixed;
|
||||
bottom: 30px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background-color: rgba(0, 0, 0, 0.7);
|
||||
color: white;
|
||||
padding: 8px 16px;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
z-index: 10001;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: opacity 0.3s ease, visibility 0.3s ease;
|
||||
}
|
||||
|
||||
.upage-share-success.active {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
/* 微信分享二维码弹窗样式 */
|
||||
.upage-wechat-modal {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 10001;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: opacity 0.3s ease, visibility 0.3s ease;
|
||||
}
|
||||
|
||||
.upage-wechat-modal.active {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.upage-wechat-content {
|
||||
width: 90%;
|
||||
max-width: 320px;
|
||||
background-color: white;
|
||||
border-radius: 12px;
|
||||
padding: 20px;
|
||||
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
|
||||
transform: scale(0.9);
|
||||
opacity: 0;
|
||||
transition: transform 0.3s ease, opacity 0.3s ease;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.upage-wechat-modal.active .upage-wechat-content {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.upage-wechat-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin: 0 0 15px 0;
|
||||
}
|
||||
|
||||
.upage-wechat-subtitle {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
margin: 0 0 20px 0;
|
||||
}
|
||||
|
||||
.upage-wechat-qrcode {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
margin: 0 auto 15px;
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.upage-wechat-qrcode img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.upage-wechat-tip {
|
||||
font-size: 13px;
|
||||
color: #888;
|
||||
margin: 0 0 20px 0;
|
||||
}
|
||||
|
||||
.upage-wechat-actions {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.upage-wechat-btn {
|
||||
flex: 1;
|
||||
padding: 10px;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.upage-wechat-btn-cancel {
|
||||
background-color: #f0f0f0;
|
||||
color: #666;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.upage-wechat-btn-cancel:hover {
|
||||
background-color: #e0e0e0;
|
||||
}
|
||||
|
||||
.upage-wechat-btn-save {
|
||||
background-color: #07C160;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.upage-wechat-btn-save:hover {
|
||||
background-color: #06AD56;
|
||||
}
|
||||
`;
|
||||
|
||||
const script = `
|
||||
(function() {
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
var shareBtn = document.querySelector('.upage-share-btn');
|
||||
var shareModal = document.querySelector('.upage-share-modal');
|
||||
var closeBtn = document.querySelector('.upage-share-close');
|
||||
var shareSuccess = document.querySelector('.upage-share-success');
|
||||
var wechatModal = document.querySelector('#wechatModal');
|
||||
var wechatQrcode = document.querySelector('#wechatQrcode');
|
||||
var wechatCancel = document.querySelector('#wechatCancel');
|
||||
var wechatSave = document.querySelector('#wechatSave');
|
||||
|
||||
if (shareBtn && shareModal) {
|
||||
shareBtn.addEventListener('click', function(e) {
|
||||
var ripple = document.createElement('span');
|
||||
ripple.classList.add('upage-ripple');
|
||||
|
||||
var rect = shareBtn.getBoundingClientRect();
|
||||
var x = e.clientX - rect.left;
|
||||
var y = e.clientY - rect.top;
|
||||
|
||||
ripple.style.left = x + 'px';
|
||||
ripple.style.top = y + 'px';
|
||||
|
||||
shareBtn.appendChild(ripple);
|
||||
|
||||
setTimeout(function() {
|
||||
ripple.remove();
|
||||
}, 600);
|
||||
|
||||
shareModal.classList.add('active');
|
||||
});
|
||||
}
|
||||
|
||||
if (closeBtn && shareModal) {
|
||||
closeBtn.addEventListener('click', function() {
|
||||
shareModal.classList.remove('active');
|
||||
});
|
||||
}
|
||||
|
||||
if (shareModal) {
|
||||
shareModal.addEventListener('click', function(e) {
|
||||
if (e.target === shareModal) {
|
||||
shareModal.classList.remove('active');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (wechatCancel && wechatModal) {
|
||||
wechatCancel.addEventListener('click', function() {
|
||||
wechatModal.classList.remove('active');
|
||||
});
|
||||
}
|
||||
|
||||
if (wechatModal) {
|
||||
wechatModal.addEventListener('click', function(e) {
|
||||
if (e.target === wechatModal) {
|
||||
wechatModal.classList.remove('active');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (wechatSave) {
|
||||
wechatSave.addEventListener('click', function() {
|
||||
var img = wechatQrcode.querySelector('img');
|
||||
if (img) {
|
||||
var a = document.createElement('a');
|
||||
a.href = img.src;
|
||||
a.download = '微信分享二维码.png';
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
|
||||
showSuccessMessage('二维码已保存');
|
||||
} else {
|
||||
showSuccessMessage('保存失败,请重试');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var shareOptions = document.querySelectorAll('.upage-share-option');
|
||||
if (shareOptions && shareOptions.length > 0) {
|
||||
shareOptions.forEach(function(option) {
|
||||
option.addEventListener('click', function() {
|
||||
var platform = this.getAttribute('data-platform');
|
||||
var url = encodeURIComponent(window.location.href);
|
||||
var shareText = '我刚刚用 UPage发布了一个页面,快来看看吧:' + window.location.href + '${recommend ? `\\n\\n注册凌霞账户,限免体验中:https://www.lxware.cn?code=${recommend}` : ''}';
|
||||
switch(platform) {
|
||||
case 'copy':
|
||||
navigator.clipboard.writeText(shareText).then(function() {
|
||||
showSuccessMessage('链接已复制到剪贴板');
|
||||
}).catch(function() {
|
||||
var tempInput = document.createElement('input');
|
||||
document.body.appendChild(tempInput);
|
||||
tempInput.value = shareText;
|
||||
tempInput.select();
|
||||
document.execCommand('copy');
|
||||
document.body.removeChild(tempInput);
|
||||
showSuccessMessage('链接已复制到剪贴板');
|
||||
});
|
||||
break;
|
||||
case 'wechat':
|
||||
generateWechatQrCode(window.location.href);
|
||||
break;
|
||||
case 'weibo':
|
||||
openShareWindow('http://service.weibo.com/share/share.php?url=' + url + '&title=' + encodeURIComponent(shareText));
|
||||
break;
|
||||
case 'twitter':
|
||||
openShareWindow('https://twitter.com/intent/tweet?text=' + encodeURIComponent(shareText));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (shareModal && platform !== 'wechat') {
|
||||
setTimeout(function() {
|
||||
shareModal.classList.remove('active');
|
||||
}, 500);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function generateWechatQrCode(url) {
|
||||
if (!wechatQrcode || !wechatModal) return;
|
||||
|
||||
wechatQrcode.innerHTML = '<div style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;">生成中...</div>';
|
||||
|
||||
try {
|
||||
if (window.QRCode && typeof window.QRCode.toDataURL === 'function') {
|
||||
window.QRCode.toDataURL(url, {
|
||||
errorCorrectionLevel: 'H',
|
||||
margin: 1,
|
||||
width: 200,
|
||||
color: {
|
||||
dark: '#000000',
|
||||
light: '#ffffff'
|
||||
}
|
||||
}, function(err, dataURL) {
|
||||
if (err || !dataURL) {
|
||||
fallbackToApiQrCode(url);
|
||||
return;
|
||||
}
|
||||
|
||||
var qrcodeImage = document.createElement('img');
|
||||
qrcodeImage.src = dataURL;
|
||||
|
||||
qrcodeImage.onload = function() {
|
||||
wechatQrcode.innerHTML = '';
|
||||
wechatQrcode.appendChild(qrcodeImage);
|
||||
shareModal.classList.remove('active');
|
||||
wechatModal.classList.add('active');
|
||||
};
|
||||
|
||||
qrcodeImage.onerror = function() {
|
||||
fallbackToApiQrCode(url);
|
||||
};
|
||||
});
|
||||
} else {
|
||||
fallbackToApiQrCode(url);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('QR code generation error:', e);
|
||||
fallbackToApiQrCode(url);
|
||||
}
|
||||
}
|
||||
|
||||
function fallbackToApiQrCode(url) {
|
||||
var qrcodeImage = document.createElement('img');
|
||||
qrcodeImage.src = 'https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=' + encodeURIComponent(url);
|
||||
|
||||
qrcodeImage.onload = function() {
|
||||
wechatQrcode.innerHTML = '';
|
||||
wechatQrcode.appendChild(qrcodeImage);
|
||||
shareModal.classList.remove('active');
|
||||
wechatModal.classList.add('active');
|
||||
};
|
||||
|
||||
qrcodeImage.onerror = function() {
|
||||
wechatQrcode.innerHTML = '<div style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;color:red;">生成失败</div>';
|
||||
showSuccessMessage('二维码生成失败,请重试');
|
||||
};
|
||||
}
|
||||
|
||||
function showSuccessMessage(message) {
|
||||
if (shareSuccess) {
|
||||
shareSuccess.textContent = message;
|
||||
shareSuccess.classList.add('active');
|
||||
|
||||
setTimeout(function() {
|
||||
shareSuccess.classList.remove('active');
|
||||
}, 2000);
|
||||
}
|
||||
}
|
||||
|
||||
function openShareWindow(url) {
|
||||
window.open(url, '_blank', 'width=600,height=500,toolbar=no,menubar=no,scrollbars=yes,resizable=yes');
|
||||
}
|
||||
});
|
||||
})();
|
||||
`;
|
||||
|
||||
return (
|
||||
<>
|
||||
<script dangerouslySetInnerHTML={{ __html: qrcode }} />
|
||||
<script dangerouslySetInnerHTML={{ __html: script }} />
|
||||
<style dangerouslySetInnerHTML={{ __html: styles }} />
|
||||
|
||||
<div className="upage-share-btn">
|
||||
<div className="upage-share-icon" dangerouslySetInnerHTML={{ __html: shareIcon }}></div>
|
||||
<span className="upage-text">分享</span>
|
||||
</div>
|
||||
|
||||
<div className="upage-share-modal">
|
||||
<div className="upage-share-content">
|
||||
<div className="upage-share-header">
|
||||
<h3 className="upage-share-title">分享页面</h3>
|
||||
<button className="upage-share-close" dangerouslySetInnerHTML={{ __html: closeIcon }}></button>
|
||||
</div>
|
||||
|
||||
<div className="upage-share-options">
|
||||
<div className="upage-share-option" data-platform="copy">
|
||||
<div className="upage-share-option-icon" dangerouslySetInnerHTML={{ __html: copyIcon }}></div>
|
||||
<span className="upage-share-option-name">复制链接</span>
|
||||
</div>
|
||||
|
||||
<div className="upage-share-option" data-platform="wechat">
|
||||
<div className="upage-share-option-icon" dangerouslySetInnerHTML={{ __html: wechatIcon }}></div>
|
||||
<span className="upage-share-option-name">微信</span>
|
||||
</div>
|
||||
|
||||
<div className="upage-share-option" data-platform="weibo">
|
||||
<div className="upage-share-option-icon" dangerouslySetInnerHTML={{ __html: weiboIcon }}></div>
|
||||
<span className="upage-share-option-name">微博</span>
|
||||
</div>
|
||||
|
||||
<div className="upage-share-option" data-platform="twitter">
|
||||
<div className="upage-share-option-icon" dangerouslySetInnerHTML={{ __html: twitterIcon }}></div>
|
||||
<span className="upage-share-option-name">Twitter</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="upage-wechat-modal" id="wechatModal">
|
||||
<div className="upage-wechat-content">
|
||||
<h3 className="upage-wechat-title">微信分享</h3>
|
||||
<p className="upage-wechat-subtitle">请扫描二维码或长按识别</p>
|
||||
<div className="upage-wechat-qrcode" id="wechatQrcode"></div>
|
||||
<p className="upage-wechat-tip">长按二维码可保存或识别</p>
|
||||
<div className="upage-wechat-actions">
|
||||
<button className="upage-wechat-btn upage-wechat-btn-cancel" id="wechatCancel">
|
||||
取消
|
||||
</button>
|
||||
<button className="upage-wechat-btn upage-wechat-btn-save" id="wechatSave">
|
||||
保存到相册
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="upage-share-success"></div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
3
app/components/upage/icons/close.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path fill="currentColor" d="M13.46 12L19 17.54V19h-1.46L12 13.46L6.46 19H5v-1.46L10.54 12L5 6.46V5h1.46L12 10.54L17.54 5H19v1.46z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 226 B |
6
app/components/upage/icons/copy.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
|
||||
<rect width="14" height="14" x="8" y="8" rx="2" ry="2" />
|
||||
<path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 330 B |
1
app/components/upage/icons/logo.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class=""><rect id="«r39»" width="512" height="512" x="0" y="0" rx="" fill="url(#«r3a»)" stroke="#FFFFFF" stroke-width="0" stroke-opacity="100%" paint-order="stroke"></rect><clipPath id="clip"><use xlink:href="#«r39»"></use></clipPath><defs><radialGradient id="«r3a»" cx="50%" cy="50%" r="100%" fx="50%" fy="0%" gradientUnits="objectBoundingBox"><stop stop-color="#68AEFF"></stop><stop offset="1" stop-color="#003EB7"></stop></radialGradient><radialGradient id="«r3b»" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(256) rotate(90) scale(512)"><stop stop-color="white"></stop><stop offset="1" stop-color="white" stop-opacity="0"></stop></radialGradient></defs><svg xmlns="http://www.w3.org/2000/svg" width="352" height="352" viewBox="0 0 24 24" x="80" y="80" alignment-baseline="middle" style="color: rgb(255, 255, 255);"><g fill="none"><path d="m12.594 23.258l-.012.002l-.071.035l-.02.004l-.014-.004l-.071-.036q-.016-.004-.024.006l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.016-.018m.264-.113l-.014.002l-.184.093l-.01.01l-.003.011l.018.43l.005.012l.008.008l.201.092q.019.005.029-.008l.004-.014l-.034-.614q-.005-.019-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.003-.011l.018-.43l-.003-.012l-.01-.01z"></path><path fill="#fff" d="M9.107 5.448c.598-1.75 3.016-1.803 3.725-.159l.06.16l.807 2.36a4 4 0 0 0 2.276 2.411l.217.081l2.36.806c1.75.598 1.803 3.016.16 3.725l-.16.06l-2.36.807a4 4 0 0 0-2.412 2.276l-.081.216l-.806 2.361c-.598 1.75-3.016 1.803-3.724.16l-.062-.16l-.806-2.36a4 4 0 0 0-2.276-2.412l-.216-.081l-2.36-.806c-1.751-.598-1.804-3.016-.16-3.724l.16-.062l2.36-.806A4 4 0 0 0 8.22 8.025l.081-.216zM11 6.094l-.806 2.36a6 6 0 0 1-3.49 3.649l-.25.091l-2.36.806l2.36.806a6 6 0 0 1 3.649 3.49l.091.25l.806 2.36l.806-2.36a6 6 0 0 1 3.49-3.649l.25-.09l2.36-.807l-2.36-.806a6 6 0 0 1-3.649-3.49l-.09-.25zM19 2a1 1 0 0 1 .898.56l.048.117l.35 1.026l1.027.35a1 1 0 0 1 .118 1.845l-.118.048l-1.026.35l-.35 1.027a1 1 0 0 1-1.845.117l-.048-.117l-.35-1.026l-1.027-.35a1 1 0 0 1-.118-1.845l.118-.048l1.026-.35l.35-1.027A1 1 0 0 1 19 2"></path></g></svg></svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
3
app/components/upage/icons/share.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path fill="currentColor" d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81c1.66 0 3-1.34 3-3s-1.34-3-3-3s-3 1.34-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9c-1.66 0-3 1.34-3 3s1.34 3 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66c0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91s-1.31-2.92-2.92-2.92M18 4c.55 0 1 .45 1 1s-.45 1-1 1s-1-.45-1-1s.45-1 1-1M6 13c-.55 0-1-.45-1-1s.45-1 1-1s1 .45 1 1s-.45 1-1 1m12 7c-.55 0-1-.45-1-1s.45-1 1-1s1 .45 1 1s-.45 1-1 1" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 635 B |
3
app/components/upage/icons/twitter.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path fill="currentColor" d="M22.46 6c-.77.35-1.6.58-2.46.69c.88-.53 1.56-1.37 1.88-2.38c-.83.5-1.75.85-2.72 1.05C18.37 4.5 17.26 4 16 4c-2.35 0-4.27 1.92-4.27 4.29c0 .34.04.67.11.98C8.28 9.09 5.11 7.38 3 4.79c-.37.63-.58 1.37-.58 2.15c0 1.49.75 2.81 1.91 3.56c-.71 0-1.37-.2-1.95-.5v.03c0 2.08 1.48 3.82 3.44 4.21a4.2 4.2 0 0 1-1.93.07a4.28 4.28 0 0 0 4 2.98a8.52 8.52 0 0 1-5.33 1.84q-.51 0-1.02-.06C3.44 20.29 5.7 21 8.12 21C16 21 20.33 14.46 20.33 8.79c0-.19 0-.37-.01-.56c.84-.6 1.56-1.36 2.14-2.23" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 599 B |
3
app/components/upage/icons/wechat.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path fill="currentColor" d="M9.5 4C5.36 4 2 6.69 2 10c0 1.89 1.08 3.56 2.78 4.66L4 17l2.5-1.5c.89.31 1.87.5 2.91.5A5.2 5.2 0 0 1 9 14c0-3.31 3.13-6 7-6c.19 0 .38 0 .56.03C15.54 5.69 12.78 4 9.5 4m-3 2.5a1 1 0 0 1 1 1a1 1 0 0 1-1 1a1 1 0 0 1-1-1a1 1 0 0 1 1-1m5 0a1 1 0 0 1 1 1a1 1 0 0 1-1 1a1 1 0 0 1-1-1a1 1 0 0 1 1-1M16 9c-3.31 0-6 2.24-6 5s2.69 5 6 5c.67 0 1.31-.08 1.91-.25L20 20l-.62-1.87C20.95 17.22 22 15.71 22 14c0-2.76-2.69-5-6-5m-2 2.5a1 1 0 0 1 1 1a1 1 0 0 1-1 1a1 1 0 0 1-1-1a1 1 0 0 1 1-1m4 0a1 1 0 0 1 1 1a1 1 0 0 1-1 1a1 1 0 0 1-1-1a1 1 0 0 1 1-1" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 658 B |
3
app/components/upage/icons/weibo.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path fill="currentColor" d="M9.82 13.87c1.07 0 1.95.87 1.95 1.95a1.95 1.95 0 0 1-1.95 1.95c-1.08 0-1.95-.88-1.95-1.95c0-1.08.87-1.95 1.95-1.95M14.5 3.34l.68-.03c3.76 0 6.82 3.06 6.82 6.82l-.05.82l-1.19-.37l.02-.45c0-3.09-2.51-5.6-5.6-5.6l-.35.01zm.82 2.89c2.06.07 3.73 1.77 3.76 3.83l-1.24-.38c-.19-1.12-1.06-2-2.17-2.18zM2 15.41c-.03-.61.07-2.77 2.95-5.44c3.4-3.16 4.87-2.92 4.87-2.92s3.18-.3 1.24 3.41h.07c.47-.5 1.49-1.25 3.56-1.46c2.08-.21 2.08 1.5 1.81 2.7c1.88.94 3.06 2.33 3.06 3.88c0 2.82-3.93 5.11-8.78 5.11h-.28c-3.5 0-6.5-1.27-7.79-3.1c-.46-.62-.71-1.3-.71-2.01zm7.82-3.49c-3.23 0-5.85 1.75-5.85 3.9s2.62 3.9 5.85 3.9s5.85-1.75 5.85-3.9s-2.62-3.9-5.85-3.9" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 763 B |