mirror of
https://github.com/mickael-kerjean/filestash.git
synced 2025-11-01 10:56:31 +08:00
feature (chromecast): canary release with chromecast image
This commit is contained in:
@ -82,17 +82,6 @@ async function setup_blue_death_screen() {
|
||||
};
|
||||
}
|
||||
|
||||
// async function setup_chromecast() {
|
||||
// if (!window.CONFIG["enable_chromecast"]) {
|
||||
// return Promise.resolve();
|
||||
// } else if (!("chrome" in window)) {
|
||||
// return Promise.resolve();
|
||||
// } else if (location.hostname === "localhost" || location.hostname === "127.0.0.1") {
|
||||
// return Promise.resolve();
|
||||
// }
|
||||
// return window.Chromecast.init();
|
||||
// }
|
||||
|
||||
async function setup_history() {
|
||||
window.history.replaceState({}, "");
|
||||
}
|
||||
|
||||
@ -6,76 +6,60 @@ export async function init() {
|
||||
} else if (location.hostname === "localhost" || location.hostname === "127.0.0.1") {
|
||||
return Promise.resolve();
|
||||
}
|
||||
// return Chromecast.init();
|
||||
return Chromecast.init();
|
||||
}
|
||||
|
||||
// import { Session } from "./session";
|
||||
// import { currentShare, objectGet } from "../helpers/";
|
||||
export const Chromecast = new class ChromecastManager {
|
||||
init() {
|
||||
return new Promise((resolve) => {
|
||||
const script = document.createElement("script");
|
||||
script.src = "https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1";
|
||||
script.onerror = () => resolve(null);
|
||||
window["__onGCastApiAvailable"] = function(isAvailable) {
|
||||
if (isAvailable) window.cast.framework.CastContext.getInstance().setOptions({
|
||||
receiverApplicationId: window.chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID,
|
||||
autoJoinPolicy: window.chrome.cast.AutoJoinPolicy.ORIGIN_SCOPED,
|
||||
});
|
||||
resolve(null);
|
||||
};
|
||||
document.head.appendChild(script);
|
||||
});
|
||||
}
|
||||
|
||||
// class ChromecastManager {
|
||||
// init() {
|
||||
// return new Promise((done) => {
|
||||
// const script = document.createElement("script");
|
||||
// script.src = "https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1";
|
||||
// script.onerror = () => done()
|
||||
// window["__onGCastApiAvailable"] = function(isAvailable) {
|
||||
// if (isAvailable) cast.framework.CastContext.getInstance().setOptions({
|
||||
// receiverApplicationId: chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID,
|
||||
// autoJoinPolicy: chrome.cast.AutoJoinPolicy.ORIGIN_SCOPED,
|
||||
// });
|
||||
// done();
|
||||
// };
|
||||
// document.head.appendChild(script)
|
||||
// });
|
||||
// }
|
||||
createLink(apiPath) {
|
||||
const target = new URL(location.origin + apiPath);
|
||||
const shareID = new URLSearchParams(location.search).get("search");
|
||||
if (shareID) target.searchParams.append("share", shareID);
|
||||
return target.toString();
|
||||
}
|
||||
|
||||
// origin() {
|
||||
// return location.origin;
|
||||
// };
|
||||
createRequest(mediaInfo) {
|
||||
if (!window.BEARER_TOKEN) throw new Error("Invalid account");
|
||||
// TODO: it would be much much nicer to set the authorization from an HTTP header
|
||||
// but this would require to create a custom web receiver app, setup accounts on
|
||||
// google, etc,... Until that happens, we're setting the authorization within the
|
||||
// url. Once we have that app, the authorisation will come from a customData field
|
||||
// of a chrome.cast.media.LoadRequest
|
||||
const target = new URL(mediaInfo.contentId);
|
||||
target.searchParams.append("authorization", window.BEARER_TOKEN);
|
||||
mediaInfo.contentId = target.toString();
|
||||
return new window.chrome.cast.media.LoadRequest(mediaInfo);
|
||||
}
|
||||
|
||||
// createLink(apiPath) {
|
||||
// const shareID = currentShare();
|
||||
// if (shareID) {
|
||||
// const target = new URL(this.origin() + apiPath);
|
||||
// target.searchParams.append("share", shareID);
|
||||
// return target.toString();
|
||||
// }
|
||||
// const target = new URL(this.origin() + apiPath)
|
||||
// return target.toString();
|
||||
// }
|
||||
context() {
|
||||
if (!window.chrome?.cast?.isAvailable) return;
|
||||
return window.cast.framework.CastContext.getInstance();
|
||||
}
|
||||
|
||||
// createRequest(mediaInfo) {
|
||||
// let prior = Promise.resolve();
|
||||
// if (!Session.authorization) prior = Session.currentUser();
|
||||
// return prior.then(() => {
|
||||
// if (!Session.authorization) throw new Error("Invalid account");
|
||||
// // TODO: it would be much much nicer to set the authorization from an HTTP header
|
||||
// // but this would require to create a custom web receiver app, setup accounts on
|
||||
// // google, etc,... Until that happens, we're setting the authorization within the
|
||||
// // url. Once we have that app, the authorisation will come from a customData field
|
||||
// // of a chrome.cast.media.LoadRequest
|
||||
// const target = new URL(mediaInfo.contentId);
|
||||
// target.searchParams.append("authorization", Session.authorization);
|
||||
// mediaInfo.contentId = target.toString();
|
||||
// return new chrome.cast.media.LoadRequest(mediaInfo);
|
||||
// });
|
||||
// }
|
||||
session() {
|
||||
const context = this.context();
|
||||
if (!context) return;
|
||||
return context.getCurrentSession();
|
||||
}
|
||||
|
||||
// context() {
|
||||
// if (!objectGet(window.chrome, ["cast", "isAvailable"])) {
|
||||
// return;
|
||||
// }
|
||||
// return cast.framework.CastContext.getInstance();
|
||||
// }
|
||||
// session() {
|
||||
// const context = this.context();
|
||||
// if (!context) return;
|
||||
// return context.getCurrentSession();
|
||||
// }
|
||||
// media() {
|
||||
// const session = this.session();
|
||||
// if (!session) return;
|
||||
// return session.getMediaSession();
|
||||
// }
|
||||
// }
|
||||
// export const Chromecast = new ChromecastManager();
|
||||
media() {
|
||||
const session = this.session();
|
||||
if (!session) return;
|
||||
return session.getMediaSession();
|
||||
}
|
||||
}();
|
||||
|
||||
@ -8,7 +8,10 @@ export function getSession() {
|
||||
method: "GET",
|
||||
responseType: "json"
|
||||
}).pipe(
|
||||
rxjs.map(({ responseJSON }) => responseJSON.result)
|
||||
rxjs.map(({ responseJSON }) => responseJSON.result),
|
||||
rxjs.tap(({ authorization }) => {
|
||||
if (authorization) window.BEARER_TOKEN = authorization;
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -198,7 +198,7 @@ export default async function(render) {
|
||||
return rxjs.of(null).pipe(
|
||||
rxjs.tap(() => toggleLoader(true)),
|
||||
rxjs.mergeMap(() => createSession(formData)),
|
||||
rxjs.tap(({ responseJSON, responseHeaders }) => {
|
||||
rxjs.tap(({ responseJSON }) => {
|
||||
let redirectURL = toHref("/files/");
|
||||
const GET = getURLParams();
|
||||
if (GET["next"]) redirectURL = GET["next"];
|
||||
|
||||
@ -13,7 +13,7 @@ export default function(render) {
|
||||
effect(deleteSession().pipe(
|
||||
rxjs.mergeMap(setup_config),
|
||||
rxjs.tap(() => {
|
||||
window.CONFIG["logout"] ? location.href = window.CONFIG["logout"] : navigate(toHref("/"))
|
||||
window.CONFIG["logout"] ? location.href = window.CONFIG["logout"] : navigate(toHref("/"));
|
||||
}),
|
||||
rxjs.catchError(ctrlError(render)),
|
||||
));
|
||||
|
||||
@ -1,11 +1,15 @@
|
||||
import { createElement, createRender } from "../../lib/skeleton/index.js";
|
||||
import { createElement, createRender, onDestroy } from "../../lib/skeleton/index.js";
|
||||
import { toHref } from "../../lib/skeleton/router.js";
|
||||
import rxjs, { effect, onLoad, onClick } from "../../lib/rx.js";
|
||||
import { animate } from "../../lib/animate.js";
|
||||
import { extname } from "../../lib/path.js";
|
||||
import { loadCSS } from "../../helpers/loader.js";
|
||||
import { qs } from "../../lib/dom.js";
|
||||
import { createLoader } from "../../components/loader.js";
|
||||
import notification from "../../components/notification.js";
|
||||
import t from "../../locales/index.js";
|
||||
import ctrlError from "../ctrl_error.js";
|
||||
import { Chromecast } from "../../model/chromecast.js";
|
||||
|
||||
import { transition, getFilename, getDownloadUrl } from "./common.js";
|
||||
|
||||
@ -44,6 +48,7 @@ export default function(render) {
|
||||
buttonDownload(getFilename(), getDownloadUrl()),
|
||||
buttonFullscreen(qs($page, ".component_image_container")),
|
||||
buttonInfo({ toggle: toggleInfo }),
|
||||
buttonChromecast(getFilename(), getDownloadUrl()),
|
||||
);
|
||||
|
||||
effect(onLoad($photo).pipe(
|
||||
@ -85,6 +90,13 @@ export default function(render) {
|
||||
componentPager(createRender(qs($page, ".component_pager")));
|
||||
}
|
||||
|
||||
export function init() {
|
||||
return Promise.all([
|
||||
loadCSS(import.meta.url, "./application_image.css"),
|
||||
initPager(), initMetadata(),
|
||||
]);
|
||||
}
|
||||
|
||||
function buttonInfo({ toggle }) {
|
||||
const $el = createElement(`
|
||||
<span>
|
||||
@ -98,9 +110,51 @@ function buttonInfo({ toggle }) {
|
||||
return $el;
|
||||
}
|
||||
|
||||
export function init() {
|
||||
return Promise.all([
|
||||
loadCSS(import.meta.url, "./application_image.css"),
|
||||
initPager(), initMetadata(),
|
||||
]);
|
||||
function buttonChromecast(filename, downloadURL) {
|
||||
const context = Chromecast.context();
|
||||
if (!context) return;
|
||||
|
||||
const chromecastSetup = (event) => {
|
||||
switch (event.sessionState) {
|
||||
case window.cast.framework.SessionState.SESSION_STARTED:
|
||||
chromecastLoader();
|
||||
break;
|
||||
}
|
||||
};
|
||||
const chromecastLoader = () => {
|
||||
const session = Chromecast.session();
|
||||
if (!session) return;
|
||||
|
||||
const link = Chromecast.createLink("/" + toHref(downloadURL));
|
||||
const media = new window.chrome.cast.media.MediaInfo(
|
||||
link,
|
||||
window.CONFIG.mime[extname(filename)],
|
||||
);
|
||||
media.metadata = new window.chrome.cast.media.PhotoMediaMetadata();
|
||||
media.metadata.title = filename;
|
||||
media.metadata.images = [
|
||||
new window.chrome.cast.Image(location.origin + "/" + toHref("/assets/icons/photo.png")),
|
||||
];
|
||||
try {
|
||||
const req = Chromecast.createRequest(media);
|
||||
session.loadMedia(req);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
notification.error(t("Cannot establish a connection"));
|
||||
}
|
||||
};
|
||||
|
||||
context.addEventListener(
|
||||
window.cast.framework.CastContextEventType.SESSION_STATE_CHANGED,
|
||||
chromecastSetup,
|
||||
);
|
||||
onDestroy(() => context.removeEventListener(
|
||||
window.cast.framework.CastContextEventType.SESSION_STATE_CHANGED,
|
||||
chromecastSetup,
|
||||
));
|
||||
|
||||
const media = Chromecast.media();
|
||||
if (media && media.media && media.media.mediaCategory === "IMAGE") chromecastLoader();
|
||||
|
||||
return document.createElement("google-cast-launcher");
|
||||
}
|
||||
|
||||
@ -30,7 +30,6 @@ export default async function(render) {
|
||||
|
||||
const map = window.L.map("map");
|
||||
|
||||
|
||||
const fileview = [getFilename()];
|
||||
for (let i=0; i<fileview.length; i++) {
|
||||
await cat(fileview[i]).pipe(rxjs.mergeMap(async(content) => {
|
||||
|
||||
4
public/global.d.ts
vendored
4
public/global.d.ts
vendored
@ -1,10 +1,12 @@
|
||||
interface Window {
|
||||
chrome: object;
|
||||
chrome: any;
|
||||
cast: any;
|
||||
overrides: {
|
||||
[key: string]: any;
|
||||
"xdg-open"?: (mime: string) => void;
|
||||
};
|
||||
CONFIG: Config;
|
||||
BEARER_TOKEN?: string;
|
||||
}
|
||||
|
||||
interface Config {
|
||||
|
||||
Reference in New Issue
Block a user