Skip to content

Commit 2d7e5a9

Browse files
committed
Improve changelog media sizing
1 parent fa70eca commit 2d7e5a9

2 files changed

Lines changed: 227 additions & 0 deletions

File tree

static/main.js

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ fetch('https://api.github.com/repositories/42366054/releases?per_page=5', {
127127
const releaseContent = document.createElement('div');
128128
releaseContent.className = 'release-content';
129129
releaseContent.innerHTML = release.body_html;
130+
AdjustChangelog(releaseContent);
130131
releaseMain.appendChild(releaseContent);
131132

132133
if (isLatest) {
@@ -166,6 +167,99 @@ fetch('https://api.github.com/repositories/42366054/releases?per_page=5', {
166167
});
167168
});
168169

170+
function AdjustChangelog(changelogContainer) {
171+
// Handle images
172+
const images = changelogContainer.querySelectorAll('img');
173+
images.forEach(img => {
174+
// Remove parent link to prevent new-tab navigation
175+
const parentLink = img.closest('a');
176+
if (parentLink && parentLink.href === img.src) {
177+
const wrapper = document.createElement('div');
178+
wrapper.className = 'changelog-img-wrapper';
179+
parentLink.parentNode.insertBefore(wrapper, parentLink);
180+
wrapper.appendChild(img);
181+
parentLink.remove();
182+
} else if (!img.closest('.changelog-img-wrapper')) {
183+
const wrapper = document.createElement('div');
184+
wrapper.className = 'changelog-img-wrapper';
185+
img.parentNode.insertBefore(wrapper, img);
186+
wrapper.appendChild(img);
187+
}
188+
189+
// Add click handler for modal
190+
img.style.cursor = 'zoom-in';
191+
img.addEventListener('click', (e) => {
192+
e.preventDefault();
193+
OpenMediaModal(img.src, img.alt, 'image');
194+
});
195+
});
196+
197+
// Handle videos
198+
const videos = changelogContainer.querySelectorAll('video');
199+
videos.forEach(video => {
200+
// Remove outer details/summary wrapper if present
201+
const detailsParent = video.closest('details');
202+
if (detailsParent) {
203+
const wrapper = document.createElement('div');
204+
wrapper.className = 'changelog-video-wrapper';
205+
detailsParent.parentNode.insertBefore(wrapper, detailsParent);
206+
wrapper.appendChild(video);
207+
detailsParent.remove();
208+
} else if (!video.closest('.changelog-video-wrapper')) {
209+
const wrapper = document.createElement('div');
210+
wrapper.className = 'changelog-video-wrapper';
211+
video.parentNode.insertBefore(wrapper, video);
212+
wrapper.appendChild(video);
213+
}
214+
215+
// Add click handler for modal
216+
video.style.cursor = 'zoom-in';
217+
video.addEventListener('click', (e) => {
218+
e.preventDefault();
219+
OpenMediaModal(video.src || video.querySelector('source')?.src, '', 'video');
220+
});
221+
});
222+
}
223+
224+
// Media modal for changelog (images and videos)
225+
function OpenMediaModal(src, alt, type) {
226+
let modal = document.getElementById('changelog-media-modal');
227+
if (!modal) {
228+
modal = document.createElement('div');
229+
modal.id = 'changelog-media-modal';
230+
modal.className = 'changelog-modal';
231+
modal.innerHTML = `
232+
<div class="changelog-modal-backdrop">
233+
<button class="changelog-modal-close" aria-label="Close">&times;</button>
234+
<div class="changelog-modal-content"></div>
235+
</div>
236+
`;
237+
document.body.appendChild(modal);
238+
239+
const closeModal = () => {
240+
modal.classList.remove('active');
241+
const content = modal.querySelector('.changelog-modal-content');
242+
const video = content.querySelector('video');
243+
if (video) video.pause();
244+
};
245+
modal.querySelector('.changelog-modal-close').onclick = closeModal;
246+
modal.querySelector('.changelog-modal-backdrop').onclick = (e) => {
247+
if (e.target.classList.contains('changelog-modal-backdrop')) closeModal();
248+
};
249+
document.addEventListener('keydown', (e) => {
250+
if (e.key === 'Escape' && modal.classList.contains('active')) closeModal();
251+
});
252+
}
253+
254+
const content = modal.querySelector('.changelog-modal-content');
255+
if (type === 'video') {
256+
content.innerHTML = `<video class="changelog-modal-video" src="${src}" controls autoplay loop></video>`;
257+
} else {
258+
content.innerHTML = `<img class="changelog-modal-img" src="${src}" alt="${alt || ''}">`;
259+
}
260+
modal.classList.add('active');
261+
}
262+
169263
function LoadWorkshop() {
170264
fetch('https://steamdb.info/api/Source2ViewerWorkshop/')
171265
.then((response) => {

static/style.css

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,7 @@ a.hljs-built_in {
719719

720720
#changelog {
721721
padding: 1.5rem 0;
722+
--changelog-media-width: 720px;
722723

723724
> h2 {
724725
font-size: 2.5rem;
@@ -925,3 +926,135 @@ a.hljs-built_in {
925926
}
926927
}
927928
}
929+
930+
/* Changelog image optimization */
931+
.changelog-img-wrapper {
932+
display: block;
933+
max-width: var(--changelog-media-width);
934+
width: 100%;
935+
margin: 1rem auto;
936+
}
937+
938+
.changelog-img-wrapper img {
939+
width: 100%;
940+
height: auto;
941+
border-radius: 6px;
942+
border: 1px solid rgba(255, 255, 255, 0.08);
943+
transition: transform 0.2s ease, border-color 0.2s ease;
944+
}
945+
946+
.changelog-img-wrapper img:hover {
947+
border-color: var(--color-accent);
948+
transform: scale(1.02);
949+
}
950+
951+
/* Changelog video optimization */
952+
.changelog-video-wrapper {
953+
display: block;
954+
max-width: var(--changelog-media-width);
955+
width: 100%;
956+
margin: 1rem auto;
957+
}
958+
959+
.changelog-video-wrapper video {
960+
width: 100%;
961+
height: auto;
962+
border-radius: 6px;
963+
border: 1px solid rgba(255, 255, 255, 0.08);
964+
transition: transform 0.2s ease, border-color 0.2s ease;
965+
}
966+
967+
.changelog-video-wrapper video:hover {
968+
border-color: var(--color-accent);
969+
transform: scale(1.02);
970+
}
971+
972+
/* Media modal (images and videos) */
973+
.changelog-modal {
974+
display: none;
975+
position: fixed;
976+
inset: 0;
977+
z-index: 9999;
978+
animation: fadeIn 0.2s ease;
979+
}
980+
981+
.changelog-modal.active {
982+
display: block;
983+
}
984+
985+
.changelog-modal-backdrop {
986+
position: fixed;
987+
inset: 0;
988+
background: rgba(0, 0, 0, 0.92);
989+
display: flex;
990+
align-items: center;
991+
justify-content: center;
992+
padding: 2rem;
993+
backdrop-filter: blur(4px);
994+
}
995+
996+
.changelog-modal-content {
997+
display: flex;
998+
align-items: center;
999+
justify-content: center;
1000+
}
1001+
1002+
.changelog-modal-img,
1003+
.changelog-modal-video {
1004+
max-width: 100%;
1005+
max-height: 90vh;
1006+
width: auto;
1007+
height: auto;
1008+
border-radius: 8px;
1009+
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
1010+
object-fit: contain;
1011+
}
1012+
1013+
.changelog-modal-close {
1014+
position: absolute;
1015+
top: 1.5rem;
1016+
right: 1.5rem;
1017+
background: rgba(255, 255, 255, 0.1);
1018+
border: none;
1019+
color: #fff;
1020+
font-size: 2rem;
1021+
line-height: 1;
1022+
width: 48px;
1023+
height: 48px;
1024+
border-radius: 50%;
1025+
cursor: pointer;
1026+
transition: background 0.2s ease;
1027+
z-index: 10000;
1028+
}
1029+
1030+
.changelog-modal-close:hover {
1031+
background: rgba(255, 255, 255, 0.2);
1032+
}
1033+
1034+
@keyframes fadeIn {
1035+
from { opacity: 0; }
1036+
to { opacity: 1; }
1037+
}
1038+
1039+
@media (max-width: 768px) {
1040+
.changelog-img-wrapper {
1041+
max-width: 100%;
1042+
}
1043+
1044+
.changelog-modal-backdrop {
1045+
padding: 1rem;
1046+
}
1047+
1048+
.changelog-modal-img,
1049+
.changelog-modal-video {
1050+
max-height: 80vh;
1051+
}
1052+
1053+
.changelog-modal-close {
1054+
top: 1rem;
1055+
right: 1rem;
1056+
width: 40px;
1057+
height: 40px;
1058+
font-size: 1.5rem;
1059+
}
1060+
}

0 commit comments

Comments
 (0)