diff --git a/web/css/styles.css b/web/css/styles.css
index a278e8d..e713fe8 100644
--- a/web/css/styles.css
+++ b/web/css/styles.css
@@ -438,6 +438,29 @@ label[role="profile-nip5"] {
display: block;
}
+/* Media Preview */
+
+.bg-blur {
+ backdrop-filter: blur(20px);
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ z-index: var(--zModal);
+}
+.modal .media-container {
+ text-align: center;
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ z-index: calc(var(--zModal) + 1);
+}
+.modal .media-container > img {
+ object-fit: scale-down;
+ object-position: center;
+ width: 100%;
+ height: 100%;
+}
+
@media (prefers-color-scheme: dark) {
.icon.svg {
filter: invert(1);
diff --git a/web/index.html b/web/index.html
index 80977f9..9539f73 100644
--- a/web/index.html
+++ b/web/index.html
@@ -147,6 +147,14 @@
+
+
diff --git a/web/js/ui/util.js b/web/js/ui/util.js
index 7b02878..5e2cac8 100644
--- a/web/js/ui/util.js
+++ b/web/js/ui/util.js
@@ -113,3 +113,19 @@ function click_event(el) {
console.info(`thread to open: ${el.dataset.eid}`);
switch_view("thread");
}
+
+/* open_media_preview presents a modal to display an image via "url".
+ */
+function open_media_preview(url, type) {
+ const el = find_node("#media-preview");
+ el.classList.remove("closed");
+ find_node("img", el).src = url;
+ // TODO handle different medias such as audio and video
+ // TODO add loading state & error checking
+}
+
+/* close_media_preview closes any present media modal.
+ */
+function close_media_preview() {
+ find_node("#media-preview").classList.add("closed");
+}
diff --git a/web/js/util.js b/web/js/util.js
index 7fd8b14..af45d2f 100644
--- a/web/js/util.js
+++ b/web/js/util.js
@@ -169,9 +169,7 @@ function linkify(text, show_media) {
let html;
if (show_media && is_img_url(parsed.pathname)) {
html = `
-
-
-
+
`;
} else if (show_media && is_video_url(parsed.pathname)) {
html = `