From 82659c600ab2f5d1efe9bba1f7d55334d3fd385e Mon Sep 17 00:00:00 2001 From: shenjianZ Date: Mon, 28 Jul 2025 15:46:43 +0800 Subject: [PATCH] feat: fix android display --- frontend/src/App.vue | 124 +++++++++++++++++++++++++++++++--- frontend/src/assets/logo.svg | 1 + frontend/src/assets/main.css | 127 +++++++++++++++++++++++++++++++++-- 3 files changed, 237 insertions(+), 15 deletions(-) create mode 100644 frontend/src/assets/logo.svg diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 177d231..018e0a7 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -12,13 +12,22 @@

您的专属临时邮箱,无限且私密

输入任何@shenjianl.cn地址,立即在此查看收件箱。

- +
+ + +
@@ -92,6 +101,7 @@ export default { const selectedMessage = ref(null); const loading = ref(false); const showModal = ref(false); + const copyStatus = ref('idle'); // 'idle' | 'copied' // !!! 生产环境��要提示 !!! // 请务必将下面的 'yourdomain.com' 替换为您的真实域名 const domain = 'shenjianl.cn'; @@ -128,10 +138,104 @@ export default { }; const generateRandomEmail = () => { - const randomPart = Math.random().toString(36).substring(2, 10); - recipient.value = `${randomPart}@${domain}`; + const names = [ + 'alex', 'casey', 'morgan', 'jordan', 'taylor', 'jamie', 'ryan', 'drew', 'jesse', 'pat', + 'chris', 'dylan', 'aaron', 'blake', 'cameron', 'devon', 'elliot', 'finn', 'gray', 'harper', + 'kai', 'logan', 'max', 'noah', 'owen', 'quinn', 'riley', 'rowan', 'sage', 'skyler' + ]; + const places = [ + 'tokyo', 'paris', 'london', 'cairo', 'sydney', 'rio', 'moscow', 'rome', 'nile', 'everest', + 'sahara', 'amazon', 'gobi', 'andes', 'pacific', 'kyoto', 'berlin', 'dubai', 'seoul', 'milan', + 'vienna', 'prague', 'athens', 'lisbon', 'oslo', 'helsinki', 'zürich', 'geneva', 'brussels', 'amsterdam' + ]; + const concepts = [ + 'apollo', 'artemis', 'athena', 'zeus', 'thor', 'loki', 'odin', 'freya', 'phoenix', 'dragon', + 'griffin', 'sphinx', 'pyramid', 'colossus', 'acropolis', 'obelisk', 'pagoda', 'castle', 'cyberspace', 'matrix', + 'protocol', 'algorithm', 'pixel', 'vector', 'photon', 'quark', 'nova', 'pulsar', 'saga', 'voyage', + 'enigma', 'oracle', 'cipher', 'vortex', 'helix', 'axiom', 'zenith', 'epoch', 'nexus', 'trinity' + ]; + + const allLists = [names, places, concepts]; + const getRandomItem = (arr) => arr[Math.floor(Math.random() * arr.length)]; + + // Randomly pick 2 lists to combine words from + const listA = getRandomItem(allLists); + const listB = getRandomItem(allLists); + + const word1 = getRandomItem(listA); + const word2 = getRandomItem(listB); + + const number = Math.floor(Math.random() * 9000) + 1000; // Random 4-digit number + + // Randomly choose a separator + const separators = ['.', '-', '_', '']; + const separator = getRandomItem(separators); + + let prefix; + if (word1 === word2) { + // Avoids "alex.alex1234" if the same list and word are picked + prefix = `${word1}${number}`; + } else { + prefix = `${word1}${separator}${word2}${number}`; + } + + recipient.value = `${prefix}@${domain}`; }; + const copyEmail = () => { + if (!recipient.value) return; + + const textToCopy = recipient.value; + + // Modern browsers in secure contexts + if (navigator.clipboard && window.isSecureContext) { + navigator.clipboard.writeText(textToCopy).then(() => { + showCopySuccess(); + }).catch(err => { + console.error('Modern copy failed: ', err); + fallbackCopy(textToCopy); // Try fallback on error + }); + } else { + // Fallback for older browsers or insecure contexts + fallbackCopy(textToCopy); + } + }; + + const fallbackCopy = (text) => { + const textArea = document.createElement('textarea'); + textArea.value = text; + + // Make the textarea out of sight + textArea.style.position = 'fixed'; + textArea.style.top = '-9999px'; + textArea.style.left = '-9999px'; + + document.body.appendChild(textArea); + textArea.focus(); + textArea.select(); + + try { + const successful = document.execCommand('copy'); + if (successful) { + showCopySuccess(); + } else { + throw new Error('Fallback copy was unsuccessful'); + } + } catch (err) { + console.error('Fallback copy failed: ', err); + alert('复制失败!'); + } + + document.body.removeChild(textArea); + }; + + const showCopySuccess = () => { + copyStatus.value = 'copied'; + setTimeout(() => { + copyStatus.value = 'idle'; + }, 2000); + }; + const showHowItWorks = () => { showModal.value = true; }; @@ -146,10 +250,12 @@ export default { selectedMessage, loading, showModal, + copyStatus, domain, fetchMessages, selectMessage, generateRandomEmail, + copyEmail, showHowItWorks, closeModal, }; diff --git a/frontend/src/assets/logo.svg b/frontend/src/assets/logo.svg new file mode 100644 index 0000000..7ed7559 --- /dev/null +++ b/frontend/src/assets/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/src/assets/main.css b/frontend/src/assets/main.css index f286a77..ea5e119 100644 --- a/frontend/src/assets/main.css +++ b/frontend/src/assets/main.css @@ -1,4 +1,10 @@ /* Global Styles & Resets */ +*, +*::before, +*::after { + box-sizing: border-box; +} + @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap'); :root { @@ -21,6 +27,7 @@ body { color: var(--text-dark); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; + overflow-x: hidden; /* Prevent horizontal scrolling */ } /* App Container */ @@ -30,6 +37,8 @@ body { align-items: center; padding: 0 2rem; min-height: 100vh; + width: 100%; + box-sizing: border-box; } /* Header */ @@ -90,13 +99,46 @@ body { gap: 0.5rem; } -.email-input { - width: 100%; +.input-wrapper { + position: relative; + display: flex; + flex: 1; max-width: 400px; - padding: 0.75rem 1rem; +} + +.email-input { + flex: 1; + /* top, right, bottom, left */ + padding: 0.75rem 3rem 0.75rem 1rem; border: 1px solid transparent; border-radius: 8px; font-size: 1rem; + width: 100%; +} + +.btn-copy { + position: absolute; + top: 50%; + right: 0.5rem; + transform: translateY(-50%); + background: transparent; + border: none; + cursor: pointer; + color: var(--dark-grey); + display: flex; + align-items: center; + justify-content: center; + padding: 0.5rem; + border-radius: 6px; +} + +.btn-copy:hover { + background-color: var(--medium-grey); +} + +.btn-copy span { + color: var(--primary-purple); + font-weight: bold; } .email-input:focus { @@ -299,15 +341,88 @@ body { /* Responsive */ @media (max-width: 768px) { + body { + -webkit-text-size-adjust: 100%; /* Prevent iOS font scaling */ + } + + #app { + padding: 0 1rem; + } + + .app-header { + padding: 1rem 0; /* Adjust padding for mobile */ + /* Keep flex row layout for alignment */ + display: flex; + justify-content: space-between; + align-items: center; + } + + .nav-links { + margin-left: 0; /* Reset margin for mobile */ + } + + .nav-links a { + margin: 0 0 0 1rem; /* Space out the links */ + } + + .hero-section { + padding: 2rem 1.5rem; + margin-bottom: 1.5rem; + text-align: center; /* Ensure content is centered on mobile */ + } + + .hero-section h1 { + font-size: 1.8rem; + } + + .hero-section p { + font-size: 1rem; + } + + .input-group { + flex-direction: column; + align-items: stretch; + gap: 0.75rem; + } + + .email-input { + max-width: none; /* Remove max-width on mobile */ + } + + .inbox-section { + min-width: 0; /* Reset min-width */ + padding: 1rem; + } + .inbox-container { flex-direction: column; + min-height: auto; + gap: 1rem; } - .message-list, .message-detail { + + .message-list, + .message-detail { width: 100%; border-right: none; padding-right: 0; } - .input-group { - flex-direction: column; + + .message-list { + border-bottom: 1px solid var(--medium-grey); + padding-bottom: 1rem; + } + + .message-detail .empty-state { + padding: 2rem 0; + } + + .message-body { + height: auto; /* Adjust height for mobile */ + max-height: 400px; + } + + .modal-content { + width: 95%; + padding: 1.5rem; } } \ No newline at end of file