Skip to content

Commit

Permalink
Merge pull request #100 from faraplay/gallery
Browse files Browse the repository at this point in the history
Gallery improvements
  • Loading branch information
OctoNezd authored Jan 8, 2024
2 parents 29aeb10 + f1ded6f commit 7677ac8
Show file tree
Hide file tree
Showing 6 changed files with 204 additions and 127 deletions.
4 changes: 4 additions & 0 deletions src/features/expandos/css/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
text-decoration: underline !important;
}

.lg-sub-html a.caption-link {
color: var(--md-sys-color-primary);
}

.ol-post-container .expando-button {
display: none;
}
Expand Down
9 changes: 7 additions & 2 deletions src/features/expandos/expandoProvider.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import { OrderedMap } from "immutable";
export type GalleryEntryData = {
imageSrc: string;
caption?: string;
outbound_url?: string;
}

export default interface ExpandoProvider {
sitename: string;
urlregex: RegExp;
usesDataSet?: boolean;
createGalleryData: (post: HTMLDivElement) => Promise<OrderedMap<string, string>>;
canHandlePost: (post: HTMLDivElement) => boolean;
createGalleryData: (post: HTMLDivElement) => Promise<GalleryEntryData[]>;
}
184 changes: 136 additions & 48 deletions src/features/expandos/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import "./css/index.css"
import "./css/index.css";
import { OLFeature } from "../base";

import ExpandoProvider from "./expandoProvider";
import ExpandoProvider, { GalleryEntryData } from "./expandoProvider";
import RedditGallery from "./redditGallery";
import iReddIt from "./ireddit";
import YoutubeExpando from "./youtube";

import "video.js"
import "video.js";
import "lightgallery/css/lightgallery.css";
import lightGallery from "lightgallery";
import { LightGallery } from "lightgallery/lightgallery";
Expand All @@ -19,21 +19,39 @@ import { allowBodyScroll, preventBodyScroll } from "../../utility/bodyScroll";
const expandoProviders: Array<ExpandoProvider> = [
new RedditGallery(),
new iReddIt(),
new YoutubeExpando()
new YoutubeExpando(),
];

enum ClosingState {
open,
closed,
closeByHistoryNavigation,
}

type Gallery = {
data: GalleryData;
lightGallery: LightGallery;
};

type GalleryData = {
id: string;
entries: GalleryEntryData[];
};

export default class Expandos extends OLFeature {
moduleName = "Expandos";
moduleId = "expandos";
async init() {
window.addEventListener("popstate", (event) => {
if (this.activeGallery !== null) {
this.activeGallery.closeGallery(true);
this.activeGallery = null;
}
});
window.addEventListener("popstate", this.onPopState.bind(this));
addEventListener("DOMContentLoaded", () =>
this.closeAndOpenGallery(history.state)
);
}
async onPost(post: HTMLDivElement) {
const postId = post.dataset.fullname;
if (typeof postId !== "string") {
throw new Error("Post does not have an id!");
}
const thumbnailLink = post.querySelector(".thumbnail");
if (!thumbnailLink) return;
const expando_btn =
Expand All @@ -47,29 +65,44 @@ export default class Expandos extends OLFeature {

thumbnailDiv.addEventListener("click", async (e) => {
e.preventDefault();
const expando_btn_R =
post.querySelector<HTMLButtonElement>(".expando-button");
const gallery = await this.getGallery(post);
this.activeGallery = gallery;
if (gallery) {
preventBodyScroll();
history.pushState({"galleryId": post.dataset.fullname}, '', "#gallery");
gallery.openGallery();
} else if (expando_btn_R) {
console.log("Clicking on expando btn", expando_btn)
history.pushState(
gallery.data,
"",
`#gallery_${gallery.data.id}`
);
this.openGallery(gallery);
return;
}

const expando_btn_R =
post.querySelector<HTMLButtonElement>(".expando-button");
if (expando_btn_R) {
console.log("Clicking on expando btn", expando_btn);
expando_btn_R.click();
} else {
console.error("Couldnt find expando button!")
console.error("Couldnt find expando button!");
}
});
}

private galleries: { [id: string]: LightGallery | null } = {};
private activeGallery: LightGallery | null = null;
private galleries: { [id: string]: Gallery | null } = {};
private activeGallery: Gallery | null = null;
private closingState: ClosingState = ClosingState.closed;

private openGallery(gallery: Gallery) {
if (this.activeGallery !== null) {
throw new Error("There is already an active gallery!");
}
preventBodyScroll();
this.closingState = ClosingState.open;
gallery.lightGallery.openGallery();
this.activeGallery = gallery;
}

private async getGallery(post: HTMLDivElement) {
const postId = post.dataset.fullname;
const url = post.dataset.url;
if (!postId) {
throw "data-fullname attribute is missing from post!";
}
Expand All @@ -78,51 +111,106 @@ export default class Expandos extends OLFeature {
}

for (const expandoProvider of expandoProviders) {
if (url && expandoProvider.urlregex.test(url)) {
const gallery = await this.createGallery(expandoProvider, post);
this.galleries[postId] = gallery;
return gallery;
if (expandoProvider.canHandlePost(post)) {
const galleryEntries = await expandoProvider.createGalleryData(
post
);
return this.createGallery(galleryEntries, postId);
}
}

console.warn(
`Couldn't find expando provider for URL ${url}, falling back to RES/reddit`
`Couldn't find expando provider for URL ${post.dataset.url}, falling back to RES/reddit`
);
this.galleries[postId] = null;
return null;
}

private async createGallery(
expandoProvider: ExpandoProvider,
post: HTMLDivElement
) {
const imgLinks = await expandoProvider.createGalleryData(post);
const gallery = document.createElement("div");
for (const [imgLink, imgDesc] of imgLinks) {
private createGallery(galleryEntries: GalleryEntryData[], postId: string) {
const lg = this.createLightGallery(galleryEntries);
const gallery = {
data: { id: postId, entries: galleryEntries },
lightGallery: lg,
};
this.galleries[postId] = gallery;
return gallery;
}

private createLightGallery(galleryEntries: GalleryEntryData[]) {
const galleryDiv = document.createElement("div");
for (const { imageSrc, caption, outbound_url } of galleryEntries) {
const imageAnchorEl = document.createElement("a");
if (expandoProvider.usesDataSet) {
imageAnchorEl.dataset.src = imgLink
imageAnchorEl.dataset.lgSize = "1280-720"
} else {
imageAnchorEl.href = imgLink;
// if (useDataSet) {
// imageAnchorEl.dataset.src = imageSrc;
// imageAnchorEl.dataset.lgSize = "1280-720";
// } else {
// imageAnchorEl.href = imageSrc;
// }
imageAnchorEl.href = imageSrc;

let captionHtml = "";
if (caption) {
const captionDiv = document.createElement("div");
captionDiv.innerText = caption;
captionHtml += captionDiv.outerHTML;
}
imageAnchorEl.dataset.subHtml = imgDesc;
if (outbound_url) {
const outboundAnchor = document.createElement("a");
outboundAnchor.href = outbound_url;
outboundAnchor.innerText = outbound_url;
outboundAnchor.classList.add("caption-link");
captionHtml += outboundAnchor.outerHTML;
}
imageAnchorEl.dataset.subHtml = captionHtml;

const imageEl = document.createElement("img");
imageEl.referrerPolicy = "no-referrer";
imageEl.src = imgLink;
imageEl.src = imageSrc;
imageAnchorEl.append(imageEl);
console.log("Anchor:", imageAnchorEl)
gallery.appendChild(imageAnchorEl);
galleryDiv.appendChild(imageAnchorEl);
}
gallery.addEventListener("lgAfterClose", function () {
allowBodyScroll();
});
const lg = lightGallery(gallery, {
galleryDiv.addEventListener(
"lgAfterClose",
this.onGalleryClose.bind(this)
);
const lg = lightGallery(galleryDiv, {
plugins: [lgVideo, lgZoom],
speed: 250,
mobileSettings: {},
videojs: true
videojs: true,
});
return lg;
}

private onPopState(ev: PopStateEvent) {
this.closeAndOpenGallery(ev.state);
}

private closeAndOpenGallery(state: GalleryData | null) {
const galleryId = state?.id;

if (this.activeGallery) {
this.closingState = ClosingState.closeByHistoryNavigation;
this.activeGallery?.lightGallery.closeGallery(true);
}

if (galleryId) {
const gallery =
this.galleries[galleryId] ??
this.createGallery(state.entries, state.id);
this.openGallery(gallery);
}
}

private onGalleryClose() {
this.activeGallery = null;
allowBodyScroll();
const wasClosedByHistoryNav =
this.closingState !== ClosingState.closeByHistoryNavigation;

this.closingState = ClosingState.closed;
if (wasClosedByHistoryNav) {
history.back();
}
}
}
17 changes: 11 additions & 6 deletions src/features/expandos/ireddit.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import { OrderedMap } from "immutable";
import ExpandoProvider from "./expandoProvider";

export default class iReddIt implements ExpandoProvider {
sitename = "i.redd.it";
urlregex = new RegExp(/https:\/\/i\.redd\.it\/.{13}.{3,}/);
canHandlePost(post: HTMLDivElement) {
const url = post.dataset.url;
return !!(url && this.urlregex.test(url));
}
async createGalleryData(post: HTMLDivElement) {
if (post.dataset.url) {
return OrderedMap([[post.dataset.url, ""]]);
}
else {
return OrderedMap<string, string>();
const url = post.dataset.url;
if (url) {
return [{
imageSrc: url
}];
} else {
return [];
}
}
}
Loading

0 comments on commit 7677ac8

Please sign in to comment.