diff --git a/assets/styles.css b/assets/styles.css index b6c7f94..44746fc 100644 --- a/assets/styles.css +++ b/assets/styles.css @@ -276,6 +276,8 @@ button { cursor: pointer; } .attachments h3 { margin: 0 0 8px; font-size: 14px; } .attachment-item { padding: 7px 0; color: #555; font-size: 13px; } .attachments a { color: var(--navy); text-decoration: underline; } +.detail-attachment-preview-link { display: block; width: fit-content; margin-bottom: 8px; } +.detail-attachment-preview { display: block; max-width: min(100%, 420px); max-height: 320px; border: 1px solid var(--line); border-radius: 4px; object-fit: contain; } .completion-notice[hidden], .completion-done-notice[hidden] { display: none; } .completion-notice { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin: 20px 22px 0; padding: 15px 17px; border: 1px solid #f0c45c; background: #fff9e8; color: #5b4500; } .completion-notice strong { display: block; margin-bottom: 4px; } diff --git a/egbim/app.js b/egbim/app.js index a4c3b9d..018a9db 100644 --- a/egbim/app.js +++ b/egbim/app.js @@ -28,6 +28,22 @@ }); } + function normalizeFeedbackAttachment(attachment) { + const item = typeof attachment === 'string' ? { url: attachment } : (attachment || {}); + const url = item.url || item.download_url || item.downloadUrl || item.file_url || item.fileUrl || item.signed_url || item.signedUrl || item.presigned_url || item.presignedUrl || ''; + const safeUrl = /^(https?:\/\/|\/)/i.test(String(url)) ? String(url) : ''; + let name = item.original_file_name || item.originalFileName || item.file_name || item.fileName || item.name || ''; + if (!name && safeUrl) { + try { + name = decodeURIComponent(new URL(safeUrl, window.location.origin).pathname.split('/').pop() || ''); + } catch (error) {} + } + name = name || '첨λΆνμΌ'; + const mimeType = item.content_type || item.contentType || item.mime_type || item.mimeType || ''; + const isImage = /^image\//i.test(String(mimeType)) || /\.(avif|gif|jpe?g|png|webp|bmp|svg)(?:$|[?#])/i.test(name) || /\.(avif|gif|jpe?g|png|webp|bmp|svg)(?:$|[?#])/i.test(safeUrl); + return { name: name, url: safeUrl, isImage: isImage }; + } + function readJson(key, fallback) { try { return JSON.parse(localStorage.getItem(key) || 'null') || fallback; } catch (error) { return fallback; } } @@ -578,7 +594,11 @@ const attachmentBox = qs('[data-detail-attachments]'); const attachments = Array.isArray(post.attachments) ? post.attachments : []; if (attachmentBox) attachmentBox.innerHTML = attachments.length ? attachments.map(function (attachment) { - return '
'; + const file = normalizeFeedbackAttachment(attachment); + if (!file.url) return ''; + const link = 'π ' + escapeHtml(file.name) + ''; + const preview = file.isImage ? '