Skip to content

Commit

Permalink
Merge pull request #440 from NeurodataWithoutBorders/fullscreen
Browse files Browse the repository at this point in the history
Create a fullscreen toggle element
  • Loading branch information
CodyCBakerPhD authored Oct 13, 2023
2 parents dae1183 + c46afb2 commit efad883
Show file tree
Hide file tree
Showing 7 changed files with 173 additions and 61 deletions.
72 changes: 72 additions & 0 deletions src/renderer/src/stories/FullScreenToggle.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { LitElement, css, html } from "lit";

import fullScreenIcon from './assets/fullscreen.svg?raw'
import fullScreenExitIcon from './assets/fullscreen_exit.svg?raw'

import { unsafeHTML } from "lit/directives/unsafe-html.js";

type FullScreenToggleProps = {
target: HTMLElement | (() => HTMLElement);
}

export class FullScreenToggle extends LitElement {
static get styles() {
return css`
:host {
display: flex;
position: absolute;
top: 10px;
right: 10px;
padding: 10px;
color: white;
background-color: gainsboro;
border: 1px solid gray;
border-radius: 10px;
cursor: pointer;
box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.3);
z-index: 1000;
opacity: 0.5;
transition: opacity 0.5s;
}
:host(:hover) {
opacity: 1;
}
`;
}

static get properties() {
return {
icon: { type: String },
};
}

declare icon: string;
declare target: FullScreenToggleProps['target'];

constructor({ target }: FullScreenToggleProps) {

super();
this.target = target;
this.icon = fullScreenIcon

const fullscreenchanged = () => this.icon = document.fullscreenElement ? fullScreenExitIcon : fullScreenIcon

this.addEventListener('click', () => {
const target = (typeof this.target === 'function' ? this.target() : this.target)

target.addEventListener("fullscreenchange", fullscreenchanged);

const fullScreenEl = document.fullscreenElement
if (!fullScreenEl) target.requestFullscreen()
else document.exitFullscreen()

})
}

render() {
return html`${unsafeHTML(this.icon)}`;
}
}

customElements.get("fullscreen-toggle") || customElements.define("fullscreen-toggle", FullScreenToggle);
6 changes: 3 additions & 3 deletions src/renderer/src/stories/List.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,10 +240,10 @@ export class List extends LitElement {

const { items, emptyMessage} = this

return items.length || !emptyMessage ? html`
return html`
<ol style=${styleMap(this.listStyles)}>
${items.map(this.#renderListItem)}
</ol>` : html`<div id="empty">${emptyMessage}</div>`
${(items.length || !emptyMessage) ? items.map(this.#renderListItem) : html`<div id="empty">${emptyMessage}</div>`}
</ol>`
}
}

Expand Down
1 change: 1 addition & 0 deletions src/renderer/src/stories/Modal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export class Modal extends LitElement {
/* Modal Body */
.modal-body {
position: relative;
overflow-y: auto;
width: 100%;
flex-grow: 1;
Expand Down
1 change: 1 addition & 0 deletions src/renderer/src/stories/assets/fullscreen.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/renderer/src/stories/assets/fullscreen_exit.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
125 changes: 72 additions & 53 deletions src/renderer/src/stories/preview/NWBFilePreview.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { run } from "../pages/guided-mode/options/utils";
import { until } from "lit/directives/until.js";
import { InstanceManager } from "../InstanceManager";
import { path } from "../../electron";
import { FullScreenToggle } from "../FullScreenToggle";

export function getSharedPath(array) {
array = array.map((str) => str.replace(/\\/g, "/")); // Convert to Mac-style path
Expand Down Expand Up @@ -55,7 +56,7 @@ class NWBPreviewInstance extends LitElement {
const isOnline = navigator.onLine;

return isOnline
? new Neurosift({ url: getURLFromFilePath(this.file, this.project) })
? new Neurosift({ url: getURLFromFilePath(this.file, this.project), fullscreen: false })
: until(
(async () => {
const htmlRep = await run("html", { nwbfile_path: this.file }, { swal: false });
Expand All @@ -71,11 +72,27 @@ customElements.get("nwb-preview-instance") || customElements.define("nwb-preview
export class NWBFilePreview extends LitElement {
static get styles() {
return css`
:host {
display: block;
width: 100%;
height: 100%;
background: white;
position: relative;
}
iframe {
width: 100%;
height: 100%;
border: 0;
}
#inspect {
display: flex;
flex-direction: column;
border-left: 1px solid gray;
box-shadow: -5px 0 5px -5px rgba(0, 0, 0, 0.5);
z-index: 1;
}
`;
}

Expand Down Expand Up @@ -105,58 +122,60 @@ export class NWBFilePreview extends LitElement {

const onlyFirstFile = fileArr.length <= 1;

return html`<div style="display: flex; height: 100%;">
<div style="flex-grow: 1;">
${(() => {
if (onlyFirstFile) return new NWBPreviewInstance(fileArr[0].info, this.project);
else {
const _instances = fileArr.map(this.createInstance);
const instances = _instances.reduce((acc, { subject, session, display }) => {
if (!acc[`sub-${subject}`]) acc[`sub-${subject}`] = {};
acc[`sub-${subject}`][`ses-${session}`] = display;
return acc;
}, {});
return new InstanceManager({ instances });
}
})()}
</div>
${this.inspect
? html`<div style="padding-left: 20px; display: flex; flex-direction: column;">
<h3 style="padding: 10px; margin: 0; background: black; color: white;">Inspector Report</h3>
${until(
(async () => {
const opts = {}; // NOTE: Currently options are handled on the Python end until exposed to the user
const title = "Inspecting your file";
const items = onlyFirstFile
? removeFilePaths(
await run(
"inspect_file",
{ nwbfile_path: fileArr[0].info.file, ...opts },
{ title }
)
) // Inspect the first file
: await (async () =>
truncateFilePaths(
await run("inspect_folder", { path, ...opts }, { title: title + "s" }),
getSharedPath(fileArr.map((o) => o.info.file))
))();
const list = new InspectorList({
items: items,
listStyles: { maxWidth: "350px" },
});
list.style.padding = "10px";
return list;
})(),
html`<small style="padding: 10px 25px;">Loading inspector report...</small>`
)}
</div>`
: ""}
</div>`;
return html` ${new FullScreenToggle({ target: this })}
<div style="display: flex; height: 100%;">
<div style="flex-grow: 1;">
${(() => {
if (onlyFirstFile) return new NWBPreviewInstance(fileArr[0].info, this.project);
else {
const _instances = fileArr.map(this.createInstance);
const instances = _instances.reduce((acc, { subject, session, display }) => {
if (!acc[`sub-${subject}`]) acc[`sub-${subject}`] = {};
acc[`sub-${subject}`][`ses-${session}`] = display;
return acc;
}, {});
return new InstanceManager({ instances });
}
})()}
</div>
${this.inspect
? html`<div id="inspect">
<h3 style="padding: 10px; margin: 0; background: black; color: white;">Inspector Report</h3>
${until(
(async () => {
const opts = {}; // NOTE: Currently options are handled on the Python end until exposed to the user
const title = "Inspecting your file";
const items = onlyFirstFile
? removeFilePaths(
await run(
"inspect_file",
{ nwbfile_path: fileArr[0].info.file, ...opts },
{ title }
)
) // Inspect the first file
: await (async () =>
truncateFilePaths(
await run("inspect_folder", { path, ...opts }, { title: title + "s" }),
getSharedPath(fileArr.map((o) => o.info.file))
))();
const list = new InspectorList({
items: items,
listStyles: { minWidth: "300px", maxWidth: "350px" },
emptyMessage: "No issues found.",
});
list.style.padding = "10px";
return list;
})(),
html`<small style="padding: 10px 25px;">Loading inspector report...</small>`
)}
</div>`
: ""}
</div>`;
}
}

Expand Down
28 changes: 23 additions & 5 deletions src/renderer/src/stories/preview/Neurosift.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { LitElement, css, html } from "lit";
import { baseUrl } from "../../globals";

import { Loader } from "../Loader";
import { FullScreenToggle } from "../FullScreenToggle";

export function getURLFromFilePath(file, projectName) {
const regexp = new RegExp(`.+(${projectName}.+)`);
Expand All @@ -12,6 +13,7 @@ export class Neurosift extends LitElement {
static get styles() {
return css`
:host {
background: white;
width: 100%;
height: 100%;
display: grid;
Expand All @@ -21,7 +23,8 @@ export class Neurosift extends LitElement {
--loader-color: hsl(200, 80%, 50%);
}
:host > * {
iframe,
.loader-container {
width: 100%;
height: 100%;
}
Expand All @@ -35,6 +38,19 @@ export class Neurosift extends LitElement {
left: 0;
}
.fullscreen-toggle {
display: flex;
position: absolute;
top: 10px;
right: 10px;
padding: 10px;
color: white;
background-color: gainsboro;
border: 1px solid gray;
border-radius: 10px;
cursor: pointer;
}
span {
font-size: 14px;
}
Expand All @@ -55,21 +71,23 @@ export class Neurosift extends LitElement {
};
}

constructor({ url } = {}) {
constructor({ url, fullscreen = true } = {}) {
super();
this.url = url;
this.fullscreen = fullscreen;
}

render() {
return this.url
? html` <div class="loader-container">
${new Loader({ message: `Loading Neurosift view...<br/><small>${this.url}</small>` })}
</div>
${this.fullscreen ? new FullScreenToggle({ target: this }) : ""}
<iframe
class="iframe-placeholder"
src="https://flatironinstitute.github.io/neurosift/?p=/nwb&url=${this.url}"
@load=${function (ev) {
ev.target.previousElementSibling.remove();
@load=${function () {
const loader = this.shadowRoot.querySelector(".loader-container");
loader.remove();
}}
></iframe>`
: ``;
Expand Down

0 comments on commit efad883

Please sign in to comment.