From 7516ae640fd79ee0c0b0b1740f1a1a5e965c599e Mon Sep 17 00:00:00 2001 From: toast Date: Fri, 5 Feb 2021 17:09:45 -0700 Subject: [PATCH 1/2] added filters to files folder, still WIP --- common/constants.js | 14 ++ scenes/SceneFilesFolder.js | 262 ++++++++++++++++++++++++++++++++++++- 2 files changed, 273 insertions(+), 3 deletions(-) diff --git a/common/constants.js b/common/constants.js index d541afc8..6d9fb1bb 100644 --- a/common/constants.js +++ b/common/constants.js @@ -114,3 +114,17 @@ export const theme = { export const gateways = { ipfs: "https://slate.textile.io/ipfs", }; + +export const filetypes = { + pdf: { type: "application", subtype: "pdf" }, + aac: { type: "audio", subtype: "aac" }, + csv: { type: "text", subtype: "csv" }, + epub: { type: "application", subtype: "epub+zip" }, + jpg: { type: "image", subtype: "jpeg" }, + mp3: { type: "audio", subtype: "mpeg" }, + mp4: { type: "video", subtype: "mpeg" }, + otf: { type: "font", subtype: "otf" }, + png: { type: "image", subtype: "png" }, + ttf: { type: "font", subtype: "ttf" }, + webm: { type: "video", subtype: "webm" }, +}; diff --git a/scenes/SceneFilesFolder.js b/scenes/SceneFilesFolder.js index 1f3afb7a..da292d12 100644 --- a/scenes/SceneFilesFolder.js +++ b/scenes/SceneFilesFolder.js @@ -1,11 +1,17 @@ import * as React from "react"; +import * as Constants from "~/common/constants"; import * as SVG from "~/common/svg"; import * as Events from "~/common/custom-events"; -import { ButtonPrimary } from "~/components/system/components/Buttons"; +import { css } from "@emotion/react"; +import { PopoverNavigation } from "~/components/system/components/PopoverNavigation"; +import { ButtonPrimary, ButtonTertiary } from "~/components/system/components/Buttons"; import { FileTypeGroup } from "~/components/core/FileTypeIcon"; import { TabGroup, PrimaryTabGroup, SecondaryTabGroup } from "~/components/core/TabGroup"; +import { CheckBox } from "~/components/system/components/CheckBox.js"; +import { Boundary } from "~/components/system/components/fragments/Boundary"; import { GlobalCarousel } from "~/components/system/components/GlobalCarousel"; +import { getPublicAndPrivateFiles } from "~/common/utilities"; import ScenePage from "~/components/core/ScenePage"; import DataView from "~/components/core/DataView"; @@ -15,9 +21,137 @@ import EmptyState from "~/components/core/EmptyState"; const POLLING_INTERVAL = 10000; +const STYLES_FILTERS_CONTAINER = css` + height: 60px; + display: flex; + flex-direction: row; + justify-content: flex-end; + align-items: flex-start; +`; + +const STYLES_TOOLTIP_ANCHOR = css` + border: 1px solid #f2f2f2; + background-color: ${Constants.system.white}; + border-radius: 4px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: flex-start; + box-shadow: 0px 8px 24px rgba(178, 178, 178, 0.2); + position: absolute; + z-index: ${Constants.zindex.tooltip}; +`; + +//toast: setting both of these to 50% width might be janky but it works +const STYLES_FILETYPE_TOOLTIP = css` + display: flex; + flex-direction: column; + justify-content: space-around; + height: 250px; +`; + +const STYLES_PRIVACY_TOOLTIP = css` + display: flex; + flex-direction: column; + justify-content: space-around; + height: 110px; +`; + export default class SceneFilesFolder extends React.Component { state = { view: 0, + filetypeTooltip: false, + privacyTooltip: false, + filters: {}, + filtersActive: false, + privacy: "ALL", + files: this.props.viewer.library[0].children, + }; + + _handleFiletypeTooltip = () => { + this.setState({ filetypeTooltip: !this.state.filetypeTooltip }); + }; + + _handlePrivacyTooltip = () => { + this.setState({ privacyTooltip: !this.state.privacyTooltip }); + }; + + _handlePrivacyFilter = (filter) => { + const viewer = this.props.viewer; + const filtered = getPublicAndPrivateFiles({ viewer }); + if (filter === "ALL") { + this.setState({ privacy: "ALL" }, this._filterFiles); + } else if (filter === "public") { + this.setState({ privacy: "public" }, this._filterFiles); + } else if (filter === "private") { + this.setState({ privacy: "private" }, this._filterFiles); + } else { + console.log("this is the worst possible scenario"); + } + }; + + _getPrivacyFiles = (filter) => { + const viewer = this.props.viewer; + const filtered = getPublicAndPrivateFiles({ viewer }); + + if (filter === "ALL") { + return viewer.library[0].children; + } else if (filter === "public") { + return filtered.publicFiles; + } else if (filter === "private") { + return filtered.privateFiles; + } else { + console.log("this is the worst possible scenario"); + } + }; + + _handleFiletypeFilter = ({ type, subtype }) => { + const key = `${type}/${subtype}`; + this.setState( + (prevState) => ({ + filters: { + ...prevState.filters, + [key]: !prevState.filters[key], + }, + }), + this._filterFiles + ); + }; + + _getKey = ({ type, subtype }) => { + const key = `${type}/${subtype}`; + return key; + }; + + _filterFiles = () => { + const privacy = this.state.privacy; + const library = this._getPrivacyFiles(privacy); + const filters = this.state.filters; + const filterKeys = Object.keys(filters).filter((key) => { + return filters[key] === true; + }); + const filteredFiles = []; + + if (filterKeys.length && library.length) { + for (const libraryObject of library) { + for (const filter of filterKeys) { + { + libraryObject.type === filter ? filteredFiles.push(libraryObject) : null; + } + } + } + this.setState((prevState) => ({ + files: filteredFiles, + filetypeTooltip: prevState.filetypeTooltip ? true : false, + filtersActive: true, + })); + } else { + this.setState((prevState) => ({ + files: library, + filetypeTooltip: prevState.filetypeTooltip ? true : false, + filtersActive: false, + })); + } }; componentDidMount = () => { @@ -117,11 +251,133 @@ export default class SceneFilesFolder extends React.Component { } /> - {this.props.viewer.library[0].children && this.props.viewer.library[0].children.length ? ( +
+
+ + + FILETYPE + + {this.state.filetypeTooltip ? ( + this.setState({ filetypeTooltip: false })} + > +
+
+ this._handleFiletypeFilter(Constants.filetypes.jpg)} + > + JPG + + this._handleFiletypeFilter(Constants.filetypes.png)} + > + PNG + + this._handleFiletypeFilter(Constants.filetypes.mp4)} + > + MP4 + + this._handleFiletypeFilter(Constants.filetypes.mp3)} + > + MP3 + + this._handleFiletypeFilter(Constants.filetypes.pdf)} + > + PDF + + this._handleFiletypeFilter(Constants.filetypes.epub)} + > + EPUB + +
+
+
+ ) : null} +
+
+ + {this.state.privacy} + + {this.state.privacyTooltip ? ( + this.setState({ privacyTooltip: false })} + > +
+
+
this._handlePrivacyFilter("ALL")} + > + ALL +
+
this._handlePrivacyFilter("public")} + > + public +
+
this._handlePrivacyFilter("private")} + > + private +
+
+
+
+ ) : null} +
+
+ {this.state.files?.length ? ( From 41fde4f7d963cdd4e2aef4cfaf89ecb316bb893e Mon Sep 17 00:00:00 2001 From: toast Date: Tue, 16 Feb 2021 15:48:47 -0700 Subject: [PATCH 2/2] props for checkbox label styling, filter typography fix --- components/system/components/CheckBox.js | 2 +- scenes/SceneFilesFolder.js | 95 ++++++++++++++++-------- 2 files changed, 64 insertions(+), 33 deletions(-) diff --git a/components/system/components/CheckBox.js b/components/system/components/CheckBox.js index ca134cea..b00bdd69 100644 --- a/components/system/components/CheckBox.js +++ b/components/system/components/CheckBox.js @@ -116,7 +116,7 @@ export class CheckBox extends React.Component { checked={this.props.value} onChange={() => this._handleChange(this.props.value)} /> - {this.props.children} + {this.props.children} ); } diff --git a/scenes/SceneFilesFolder.js b/scenes/SceneFilesFolder.js index da292d12..11a94461 100644 --- a/scenes/SceneFilesFolder.js +++ b/scenes/SceneFilesFolder.js @@ -42,19 +42,20 @@ const STYLES_TOOLTIP_ANCHOR = css` z-index: ${Constants.zindex.tooltip}; `; -//toast: setting both of these to 50% width might be janky but it works const STYLES_FILETYPE_TOOLTIP = css` display: flex; flex-direction: column; justify-content: space-around; - height: 250px; + height: 260px; `; const STYLES_PRIVACY_TOOLTIP = css` display: flex; flex-direction: column; justify-content: space-around; - height: 110px; + height: 115px; + font-family: ${Constants.font.medium}; + font-size: 16px; `; export default class SceneFilesFolder extends React.Component { @@ -64,7 +65,7 @@ export default class SceneFilesFolder extends React.Component { privacyTooltip: false, filters: {}, filtersActive: false, - privacy: "ALL", + privacy: "All", files: this.props.viewer.library[0].children, }; @@ -79,12 +80,12 @@ export default class SceneFilesFolder extends React.Component { _handlePrivacyFilter = (filter) => { const viewer = this.props.viewer; const filtered = getPublicAndPrivateFiles({ viewer }); - if (filter === "ALL") { - this.setState({ privacy: "ALL" }, this._filterFiles); - } else if (filter === "public") { - this.setState({ privacy: "public" }, this._filterFiles); - } else if (filter === "private") { - this.setState({ privacy: "private" }, this._filterFiles); + if (filter === "All") { + this.setState({ privacy: "All" }, this._filterFiles); + } else if (filter === "Public") { + this.setState({ privacy: "Public" }, this._filterFiles); + } else if (filter === "Private") { + this.setState({ privacy: "Private" }, this._filterFiles); } else { console.log("this is the worst possible scenario"); } @@ -94,12 +95,12 @@ export default class SceneFilesFolder extends React.Component { const viewer = this.props.viewer; const filtered = getPublicAndPrivateFiles({ viewer }); - if (filter === "ALL") { + if (filter === "All") { return viewer.library[0].children; - } else if (filter === "public") { - return filtered.publicFiles; - } else if (filter === "private") { - return filtered.privateFiles; + } else if (filter === "Public") { + return filtered.PublicFiles; + } else if (filter === "Private") { + return filtered.PrivateFiles; } else { console.log("this is the worst possible scenario"); } @@ -262,7 +263,7 @@ export default class SceneFilesFolder extends React.Component { : Constants.system.textGray, }} /> - FILETYPE + Filetype {this.state.filetypeTooltip ? ( this.setState({ filetypeTooltip: false })} > -
+
this._handleFiletypeFilter(Constants.filetypes.jpg)} + labelStyle={{ + fontFamily: Constants.font.medium, + fontSize: 16, + paddingTop: 0, + }} > JPG @@ -286,6 +292,11 @@ export default class SceneFilesFolder extends React.Component { value={this.state.filters[this._getKey(Constants.filetypes.png)]} style={{ padding: 5 }} onChange={() => this._handleFiletypeFilter(Constants.filetypes.png)} + labelStyle={{ + fontFamily: Constants.font.medium, + fontSize: 16, + paddingTop: 0, + }} > PNG @@ -294,6 +305,11 @@ export default class SceneFilesFolder extends React.Component { value={this.state.filters[this._getKey(Constants.filetypes.mp4)]} style={{ padding: 5 }} onChange={() => this._handleFiletypeFilter(Constants.filetypes.mp4)} + labelStyle={{ + fontFamily: Constants.font.medium, + fontSize: 16, + paddingTop: 0, + }} > MP4 @@ -302,6 +318,11 @@ export default class SceneFilesFolder extends React.Component { value={this.state.filters[this._getKey(Constants.filetypes.mp3)]} style={{ padding: 5 }} onChange={() => this._handleFiletypeFilter(Constants.filetypes.mp3)} + labelStyle={{ + fontFamily: Constants.font.medium, + fontSize: 16, + paddingTop: 0, + }} > MP3 @@ -310,6 +331,11 @@ export default class SceneFilesFolder extends React.Component { value={this.state.filters[this._getKey(Constants.filetypes.pdf)]} style={{ padding: 5 }} onChange={() => this._handleFiletypeFilter(Constants.filetypes.pdf)} + labelStyle={{ + fontFamily: Constants.font.medium, + fontSize: 16, + paddingTop: 0, + }} > PDF @@ -318,6 +344,11 @@ export default class SceneFilesFolder extends React.Component { value={this.state.filters[this._getKey(Constants.filetypes.epub)]} style={{ padding: 5 }} onChange={() => this._handleFiletypeFilter(Constants.filetypes.epub)} + labelStyle={{ + fontFamily: Constants.font.medium, + fontSize: 16, + paddingTop: 0, + }} > EPUB @@ -341,31 +372,31 @@ export default class SceneFilesFolder extends React.Component {
this._handlePrivacyFilter("ALL")} + onClick={() => this._handlePrivacyFilter("All")} > - ALL -
-
this._handlePrivacyFilter("public")} - > - public + All
this._handlePrivacyFilter("private")} + onClick={() => this._handlePrivacyFilter("Private")} > - private + Private +
+
this._handlePrivacyFilter("Public")} + > + Public