diff --git a/README.md b/README.md index 61a5320..e7068e3 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ # DeviantArt Filter -> This browser extension allows you to filter/block/hide deviations by user, keyword, and/or category on DeviantArt +> This browser extension allows you to filter/block/hide deviations by user and/or keyword on DeviantArt ## Overview -Have you ever want to block/filter deviations (a.k.a. submissions) while browsing [DeviantArt](https://www.deviantart.com)? **Well now you can!** Simply [install DeviantArt Filter](#installation) in your web browser of choice and start filtering by user, keyword, and/or category. +Have you ever want to block/filter deviations (a.k.a. submissions) while browsing [DeviantArt](https://www.deviantart.com)? **Well now you can!** Simply [install DeviantArt Filter](#installation) in your web browser of choice and start filtering by user and/or keyword. ![DeviantArt Filter Promotional Image](/promo/Screenshot_1280x800.png?raw=true) @@ -13,7 +13,6 @@ Have you ever want to block/filter deviations (a.k.a. submissions) while browsin * Fully-featured management panel for maintaining your filters and controlling functionality. * Quickly create filters from any deviation thumbnail or link. * Filter deviations by keywords in titles and/or tags (with wildcard support). -* Filter all deviations from specific categories. * Import and export filter lists for easy backup and migration. #### For more information, head to the [DeviantArt Filter website](https://rthaut.github.io/deviantART-Filter/). diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index c32272e..a7b0a31 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -8,7 +8,7 @@ "description": "The short_name (maximum of 12 characters recommended) is a short version of the app's name" }, "ExtensionDescription": { - "message": "Allows configurable filtering/removal of deviations by user, keyword, and/or category on DeviantArt.", + "message": "Allows configurable filtering/removal of deviations by user and/or keyword on DeviantArt.", "description": "The description of the application" }, "BrowserActionTitle": { @@ -132,6 +132,18 @@ "Options_EnabledPages_PageLabel_Notifications": { "message": "Notifications Page" }, + "Options_PlaceholderFunctionality_Header": { + "message": "Placeholder Appearance/Behavior" + }, + "Options_PlaceholderFunctionality_HelpText": { + "message": "Use these to control the behavior and appearance of the placeholder thumbnails that are shown for filtered deviations." + }, + "Options_PlaceholderFunctionality_OptionLabel_PreventClick": { + "message": "Prevent clicking on thumbnails for filtered deviations" + }, + "Options_PlaceholderFunctionality_OptionLabel_ShowFilterText": { + "message": "Show the filter type/value on filtered deviations" + }, "Options_ShowUpdatedPage_Header": { "message": "Show Release Notes for Updates" }, @@ -165,45 +177,30 @@ "SidebarLink_ImportExport": { "message": "Import/Export" }, - "SidebarLink_Categories": { - "message": "Category Filters" - }, "SidebarLink_Keywords": { "message": "Keyword Filters" }, "SidebarLink_Users": { "message": "User Filters" }, - "FilterTitle_Category": { - "message": "Category" - }, "FilterTitle_Keyword": { "message": "Keyword" }, "FilterTitle_User": { "message": "User" }, - "FilterTitle_Categories": { - "message": "Categories" - }, "FilterTitle_Keywords": { "message": "Keywords" }, "FilterTitle_Users": { "message": "Users" }, - "FilteredTitle_Categories": { - "message": "Filtered Categories" - }, "FilteredTitle_Keywords": { "message": "Filtered Keywords" }, "FilteredTitle_Users": { "message": "Filtered Users" }, - "Filter_Categories_PropTitle_Name": { - "message": "Category" - }, "Filter_Keywords_PropTitle_Keyword": { "message": "Keyword" }, @@ -225,25 +222,10 @@ "UnsupportedFilterError": { "message": "Unsupported filter type" }, - "CategoriesMenuLabel": { - "message": "Select a category (type to search)", - "description": "The label shown on the categories autocomplete menu" - }, - "CategoriesMenuNoOptionsText": { - "message": "No matching categories", - "description": "The text shown on the categories autocomplete menu when no options match the entered value" - }, - "CategoriesMenuErrorOption": { - "message": "Failed to load category data", - "description": "The option shown (disabled) when category data cannot be loaded" - }, "DarkModeSwitchLabel": { "message": "Dark Mode", "description": "The message displayed on the switch for toggling Dark Mode" }, - "Placeholder_Category": { - "message": "Filtered Category" - }, "Placeholder_Keyword": { "message": "Filtered Keyword" }, @@ -306,9 +288,6 @@ "CreateFiltersFromDeviation_Username_Help": { "message": "Toggle the switch to create a new user filter." }, - "CreateFiltersFromDeviation_Category_Help": { - "message": "Click on sections of the following category hierarchy to create a new category filter. (You can click on a selected section to unselect it.)" - }, "CreateFiltersFromDeviation_Tags_Help": { "message": "Select one or more of the following tags to create new keyword filters." }, @@ -356,5 +335,16 @@ "content": "$1" } } + }, + "CreateUserFilterFromDeviation_ContextMenuLabel": { + "message": "Create Filter for this User" + }, + "CreateUserFilterForUsername_ContextMenuLabel": { + "message": "Create User Filter for \"$USERNAME$\"", + "placeholders": { + "username": { + "content": "$1" + } + } } } \ No newline at end of file diff --git a/app/scripts/background/categories.js b/app/scripts/background/categories.js deleted file mode 100644 index 7bc0bbf..0000000 --- a/app/scripts/background/categories.js +++ /dev/null @@ -1,155 +0,0 @@ -const paths = []; - -const API_BASE = "https://www.deviantart.com"; -const API_PATH = "api/v1"; -const API_TYPE = "oauth2"; - -const CLIENT_ID = "3309"; -const CLIENT_SECRET = "ea9f3e16a80ed47a5221a67b7d0715ff"; - -// TODO: make this configurable? also, if a way to force-refresh cache is implemented, this could possibly be increased significantly (weeks or maybe even months) -const DAYS_TO_CACHE = 1; - -/** - * Returns an access token for the DeviantArt API - * @returns {string} the access token - */ -// TODO: should this (and related API configs) be moved to a separate library/file for re-use? -const GetToken = async () => { - try { - const response = await fetch( - `${API_BASE}/${API_TYPE}/token?` + - new URLSearchParams({ - grant_type: "client_credentials", - client_id: CLIENT_ID, - client_secret: CLIENT_SECRET, - }) - ); - const data = await response.json(); - if (!response.ok) { - throw new Error(response.statusText || response.status); - } - return data?.access_token; - } catch (ex) { - console.error("Failed to get API token", ex); - } -}; - -/** - * Returns category data for the given path - * @param {string} path the category path, formatted for DeviantArt's category tree API - * @param {string} token a valid DeviantArt API access token - * @returns {object[]} the category data - */ -const GetCategoriesForPath = async (path, token) => { - try { - const response = await fetch( - `${API_BASE}/${API_PATH}/${API_TYPE}/browse/categorytree?` + - new URLSearchParams({ - catpath: encodeURI(path), - access_token: token, - mature_content: true, - }) - ); - const data = await response.json(); - if (!response.ok) { - throw new Error(response.statusText || response.status); - } - return data?.categories; - } catch (ex) { - console.error(`Failed to get categories for path "${path}"`, ex); - } -}; - -/** - * Returns the full category title (with optional parent title's prepended) - * @param {string} title the title of a category - * @param {string} [parentTitle] (optional) the title of the parent category - * @returns {string} the full formatted title - */ -const GetFullCategoryTitle = (title, parentTitle = null) => { - if (parentTitle) { - title = parentTitle + " > " + title; - } - return title; -}; - -/** - * Recursively adds all child paths for a given category to the `paths` array - * @param {string} path the category path - * @param {string} token a valid DeviantArt API access token - * @param {string} [parentTitle] (optional) the title of the parent category - */ -const PushPathsForCategory = async (path, token, parentTitle = null) => { - const categories = await GetCategoriesForPath(path, token); - if (Array.isArray(categories) && categories.length) { - await Promise.all( - categories.map(async (category) => { - const title = GetFullCategoryTitle(category.title, parentTitle); - paths.push(title); - if (category.has_subcategory) { - await PushPathsForCategory(category.catpath, token, title); - } - }) - ); - } -}; - -/** - * Returns all DeviantArt Category paths; data is cached for `DAYS_TO_CACHE` days - */ -// TODO: instead of logging remaining time for cache time here, it would be much more useful to display it somewhere (perhaps on the dashboard?) and/or provide a way to force the cache to be refreshed -export const GetCategories = async () => { - console.time("GetCategories()"); - - try { - const { category_cache: categories } = await browser.storage.local.get( - "category_cache" - ); - console.info("Cached category data", categories); - if (categories?.date && categories?.paths?.length) { - const remainingMilliseconds = - categories?.date + DAYS_TO_CACHE * 86400 * 1000 - new Date().getTime(); - if (remainingMilliseconds > 0) { - // formatting the remaining time this way only works - // if/when the remaining time is less than 24 hours - const date = new Date(0); - date.setSeconds(remainingMilliseconds / 1000); - console.info( - "Cached category data expires in", - date.toISOString().substr(11, 8) - ); - - console.timeEnd("GetCategories()"); - return categories.paths; - } else { - console.info("Cached category data is expired"); - } - } - } catch (ex) { - console.error("Failed to retrieve categories from cache", ex); - } - - const token = await GetToken(); - await PushPathsForCategory("/", token); - - if (!paths.length) { - throw new Error("No categories returned by API"); - } - - paths.sort((a, b) => a.localeCompare(b)); - - try { - await browser.storage.local.set({ - category_cache: { - paths, - date: new Date().getTime(), - }, - }); - } catch (ex) { - console.error("Failed to store categories in cache", ex); - } - - console.timeEnd("GetCategories()"); - return paths; -}; diff --git a/app/scripts/background/filters.js b/app/scripts/background/filters.js index 58e2973..06a01ca 100644 --- a/app/scripts/background/filters.js +++ b/app/scripts/background/filters.js @@ -1,6 +1,6 @@ import { differenceBy, find, findIndex, mapKeys, uniqBy } from "lodash-es"; -export const SUPPORTED_FILTERS = ["users", "keywords", "categories"]; +export const SUPPORTED_FILTERS = ["users", "keywords"]; export const MIGRATED_FILTERS = { // tags were changed to keywords in v6, so we need to change the storage key and the property names @@ -29,13 +29,7 @@ export const FILTER_METHODS = { uniq: (array) => uniqBy(array, "keyword"), find: (array, value) => find(array, ["keyword", value.keyword]), findIndex: (array, value) => findIndex(array, ["keyword", value.keyword]), - }, - categories: { - diff: (array, values) => differenceBy(array, values, "name"), - uniq: (array) => uniqBy(array, "name"), - find: (array, value) => find(array, ["name", value.name]), - findIndex: (array, value) => findIndex(array, ["name", value.name]), - }, + } }; export const GetAllFilters = async () => { diff --git a/app/scripts/background/menus.js b/app/scripts/background/menus.js index 79ed555..263301c 100644 --- a/app/scripts/background/menus.js +++ b/app/scripts/background/menus.js @@ -1,6 +1,6 @@ import { AddFilter } from "./filters"; import { SHOW_FILTER_DEVIATION_MODAL } from "../constants/messages"; -import { TAG_URL_REGEX } from "../constants/url"; +import { TAG_URL_REGEX, USER_URL_REGEX } from "../constants/url"; export const MENUS = [ { @@ -11,6 +11,17 @@ export const MENUS = [ contexts: ["link"], targetUrlPatterns: ["*://*.deviantart.com/tag/*"], }, + { + id: "filter-user", + title: browser.i18n.getMessage( + "CreateUserFilterFromDeviation_ContextMenuLabel" + ), + contexts: ["link"], + targetUrlPatterns: [ + "*://*.deviantart.com/*/art/*", + "*://*.deviantart.com/*/journal/*", + ], + }, { id: "show-filter-modal-deviation", title: browser.i18n.getMessage( @@ -60,6 +71,14 @@ export const OnMenuClicked = (info, tab) => { } break; + case "filter-user": + if (USER_URL_REGEX.test(info.linkUrl)) { + // eslint-disable-next-line no-case-declarations + const username = USER_URL_REGEX.exec(info.linkUrl)[1]; + AddFilter("users", { username }); + } + break; + case "show-filter-modal-deviation": browser.tabs.sendMessage(tab.id, { action: SHOW_FILTER_DEVIATION_MODAL, @@ -90,6 +109,15 @@ export const OnMenuShown = (info, tab) => { keyword ), }); + } else if (USER_URL_REGEX.test(info.linkUrl)) { + // filter-user menu + const username = USER_URL_REGEX.exec(info.linkUrl)[1]; + UpdateMenuItem("filter-user", { + title: browser.i18n.getMessage( + "CreateUserFilterForUsername_ContextMenuLabel", + username + ), + }); } }; diff --git a/app/scripts/background/messages.js b/app/scripts/background/messages.js index 6742169..f83ca9a 100644 --- a/app/scripts/background/messages.js +++ b/app/scripts/background/messages.js @@ -1,4 +1,3 @@ -import { GetCategories } from "./categories"; import * as FILTERS from "./filters"; import * as MESSAGES from "../constants/messages"; @@ -34,7 +33,6 @@ export const OnRuntimeMessage = (message, sender) => { return browser.storage.local.set({ users: [], keywords: [], - categories: [], }); case MESSAGES.IMPORT_FILTERS: @@ -56,9 +54,6 @@ export const OnRuntimeMessage = (message, sender) => { ) ); - case MESSAGES.FETCH_CATEGORIES: - return GetCategories(); - case MESSAGES.HIDE_FILTER_DEVIATION_MODAL: // send the message right back to the original tab return browser.tabs.sendMessage(sender.tab.id, { diff --git a/app/scripts/background/runtime.js b/app/scripts/background/runtime.js index 0749bcd..895f95f 100644 --- a/app/scripts/background/runtime.js +++ b/app/scripts/background/runtime.js @@ -2,15 +2,11 @@ import semverClean from "semver/functions/clean"; import semverDiff from "semver/functions/diff"; import semverLT from "semver/functions/lt"; -import { GetCategories } from "./categories"; import { ImportFilters } from "./filters"; import { TAG_FILTERS_MIGRATED } from "../constants/notifications"; export const OnInstalled = ({ previousVersion, reason, temporary }) => { - // fetch and store the latest category paths - GetCategories(); - if (temporary) { // use this to simulate installs/updates for testing purposes // previousVersion = '6.1.0'; diff --git a/app/scripts/background/storage.js b/app/scripts/background/storage.js index 9dc93c4..beb893c 100644 --- a/app/scripts/background/storage.js +++ b/app/scripts/background/storage.js @@ -2,7 +2,7 @@ import { differenceWith, isEqual } from "lodash-es"; import { SendMessageToAllTabs } from "./messages"; import { LOCAL_STORAGE_CHANGED } from "../constants/messages"; -export const MONITORED_STORAGE_KEYS = ["categories", "keywords", "users"]; +export const MONITORED_STORAGE_KEYS = ["keywords", "users"]; /** * Event handler for all storage changes diff --git a/app/scripts/constants/messages.js b/app/scripts/constants/messages.js index e87a756..b42057d 100644 --- a/app/scripts/constants/messages.js +++ b/app/scripts/constants/messages.js @@ -9,6 +9,5 @@ export const RESET_FILTERS = "RESET_FILTERS"; export const IMPORT_FILTERS = "IMPORT_FILTERS"; export const EXPORT_FILTERS = "EXPORT_FILTERS"; export const FETCH_METADATA = "FETCH_METADATA"; -export const FETCH_CATEGORIES = "FETCH_CATEGORIES"; export const SHOW_FILTER_DEVIATION_MODAL = "SHOW_FILTER_DEVIATION_MODAL"; export const HIDE_FILTER_DEVIATION_MODAL = "HIDE_FILTER_DEVIATION_MODAL"; diff --git a/app/scripts/constants/url.js b/app/scripts/constants/url.js index 0d6d979..0907e70 100644 --- a/app/scripts/constants/url.js +++ b/app/scripts/constants/url.js @@ -25,10 +25,12 @@ export const PAGES = { }; export const TAG_URL_REGEX = /\/tag\/([^\/]+)/i; +export const USER_URL_REGEX = /\/([^\/]+)\/(?:art|journal)/i; export default { WILDCARD, REGEX, PAGES, TAG_URL_REGEX, + USER_URL_REGEX, }; diff --git a/app/scripts/content.js b/app/scripts/content.js index efe56f6..85a5743 100644 --- a/app/scripts/content.js +++ b/app/scripts/content.js @@ -11,10 +11,9 @@ import { PAGES } from "./constants/url"; import { SetMetadataOnThumbnail } from "./content/metadata"; -import * as CategoriesFilter from "./content/filters/categories"; import * as KeywordsFilter from "./content/filters/keywords"; import * as UsersFilter from "./content/filters/users"; -const FILTERS = [CategoriesFilter, KeywordsFilter, UsersFilter]; +const FILTERS = [KeywordsFilter, UsersFilter]; let ENABLED = true; @@ -223,6 +222,17 @@ const IsPageDisabled = async (url) => { return false; }; +/** + * Gets the value of an option specific to placeholder functionality from storage + * @param {string} optionName the placeholder option name + * @param {*} defaultValue the default value (if the option is not set in storage) + * @returns {*} the value of the placeholder option from storage (or the supplied default value) + */ +const GetPlaceholderOption = async (optionName, defaultValue) => { + const data = await browser.storage.local.get("options"); + return data?.options?.placeholders?.[optionName] ?? defaultValue; +}; + /** * Run once the content script is loaded */ @@ -240,6 +250,14 @@ const IsPageDisabled = async (url) => { if (ENABLED) { document.body.classList.add("enable-metadata-indicators"); + if (!(await GetPlaceholderOption("preventClick", true))) { + document.body.classList.add("clickable-placeholders"); + } + + if (!(await GetPlaceholderOption("showFilterText", true))) { + document.body.classList.add("hide-placeholder-text"); + } + // setup observers for thumbnails loaded after initial render next WatchForNewThumbs(SELECTORS.join(", ")); diff --git a/app/scripts/content/filters/categories.js b/app/scripts/content/filters/categories.js deleted file mode 100644 index e9a7d63..0000000 --- a/app/scripts/content/filters/categories.js +++ /dev/null @@ -1,63 +0,0 @@ -export const STORAGE_KEY = "categories"; - -export const REQUIRES_METADATA = true; - -/** - * Applies filters to a given thumbnails - * @param {HTMLElement} thumbnail the thumbnail DOM node - * @param {object[]} filters the list of filters to apply - */ -export const FilterThumbnail = (thumbnail, filters) => { - for (const filter of filters) { - if (thumbnail.matches(`[data-category^="${filter.name}" i]`)) { - SetFilterAttributesOnThumbnail(thumbnail, filter.name, "Category"); - continue; - } - } -}; - -/** - * Applies filters to the page - * Used primarily for handling added filters when local storage changes - * @param {object[]} filters list of filters to apply - * @param {string} selector CSS selector for thumbnails - */ -export const ApplyFiltersToDocument = (filters, selector) => { - const thumbnails = document.querySelectorAll(selector); - thumbnails.forEach((thumbnail) => FilterThumbnail(thumbnail, filters)); -}; - -/** - * Removes filters from the page and applies remaining active filters to each unfiltered thumbnail - * Used primarily for handling added filters when local storage changes - * @param {object[]} removedFilters list of filters to remove - * @param {object[]} activeFilters list of filters that are still active - */ -export const RemoveFiltersFromDocument = (removedFilters, activeFilters) => { - for (const filter of removedFilters) { - const thumbnails = document.querySelectorAll( - `[da-filter-category="${filter.name}" i]` - ); - for (const thumbnail of thumbnails) { - RemoveFilterAttributesOnThumbnail(thumbnail); - FilterThumbnail(thumbnail, activeFilters); - } - } -}; - -/** - * Sets attributes on a thumbnail for filtering (by category) - * @param {HTMLElement} thumbnail the thumbnail DOM node - * @param {string} category the category that matched a filter - */ -const SetFilterAttributesOnThumbnail = (thumbnail, category) => { - thumbnail.setAttribute("da-filter-category", category); -}; - -/** - * Removes attributes on a thumbnail for filtering (by category) - * @param {HTMLElement} thumbnail the thumbnail DOM node - */ -const RemoveFilterAttributesOnThumbnail = (thumbnail) => { - thumbnail.removeAttribute("da-filter-category"); -}; diff --git a/app/scripts/content/metadata.js b/app/scripts/content/metadata.js index fc42fca..298d831 100644 --- a/app/scripts/content/metadata.js +++ b/app/scripts/content/metadata.js @@ -33,7 +33,7 @@ export const SetMetadataOnThumbnail = async (thumbnail) => { * @param {object} metadata the metadata */ export const SetMetadataAttributesOnThumbnail = (thumbnail, metadata) => { - const { author_name, title, category, tags } = metadata; + const { author_name, title, tags } = metadata; if (author_name) { thumbnail.setAttribute("data-username", author_name); @@ -43,10 +43,6 @@ export const SetMetadataAttributesOnThumbnail = (thumbnail, metadata) => { thumbnail.setAttribute("data-title", title); } - if (category) { - thumbnail.setAttribute("data-category", category); - } - if (tags) { thumbnail.setAttribute( "data-tags", diff --git a/app/scripts/create-filters/CreateFiltersApp.jsx b/app/scripts/create-filters/CreateFiltersApp.jsx index 9749572..25895a1 100644 --- a/app/scripts/create-filters/CreateFiltersApp.jsx +++ b/app/scripts/create-filters/CreateFiltersApp.jsx @@ -35,7 +35,6 @@ import MetadataFiltersResults from "./components/MetadataFiltersResults"; const initialFilters = { users: [], - categories: [], keywords: [], }; diff --git a/app/scripts/create-filters/components/MetadataFiltersForm.jsx b/app/scripts/create-filters/components/MetadataFiltersForm.jsx index 187257d..0d6b398 100644 --- a/app/scripts/create-filters/components/MetadataFiltersForm.jsx +++ b/app/scripts/create-filters/components/MetadataFiltersForm.jsx @@ -9,8 +9,6 @@ import { FormControl, FormControlLabel, Switch, - Breadcrumbs, - Chip, Checkbox, List, ListItem, @@ -18,12 +16,6 @@ import { ListItemText, } from "@material-ui/core"; -import { - CheckCircleOutline as CheckCircleOutlineIcon, - RadioButtonUncheckedOutlined as RadioButtonUncheckedOutlinedIcon, - NavigateNext as NavigateNextIcon, -} from "@material-ui/icons"; - const useStyles = makeStyles((theme) => ({ fieldset: { margin: theme.spacing(0, 0, 2), @@ -51,12 +43,10 @@ const MetadataFiltersForm = ({ metadata, setFilter }) => { const [selectedUsername, setSelectedUsername] = useState(""); const [selectedTags, setSelectedTags] = useState([]); - const [selectedCategory, setSelectedCategory] = useState(""); useEffect(() => { setSelectedUsername(""); setSelectedTags([]); - setSelectedCategory(""); }, [metadata]); useEffect(() => { @@ -71,18 +61,6 @@ const MetadataFiltersForm = ({ metadata, setFilter }) => { } }, [selectedUsername]); - useEffect(() => { - if (selectedCategory.length) { - setFilter("categories", [ - { - name: selectedCategory, - }, - ]); - } else { - setFilter("categories", []); - } - }, [selectedCategory]); - useEffect(() => { if (selectedTags.length) { setFilter( @@ -99,9 +77,6 @@ const MetadataFiltersForm = ({ metadata, setFilter }) => { const username = metadata?.author_name?.trim(); const tags = metadata?.tags?.split(",").map((tag) => tag.trim()); - const categories = metadata?.category - ?.split(" > ") - .map((category) => category.trim()); const toggleTag = (tag) => { if (selectedTags.includes(tag)) { @@ -152,66 +127,7 @@ const MetadataFiltersForm = ({ metadata, setFilter }) => { )} - {username && categories && } - - {categories && ( - - - {browser.i18n.getMessage("FilterTitle_Category")} - - - - {browser.i18n.getMessage( - "CreateFiltersFromDeviation_OptionalIndicator" - )} - {" "} - {browser.i18n.getMessage( - "CreateFiltersFromDeviation_Category_Help" - )} - - }> - {categories.map((category, index, categories) => { - const current = categories - .slice(0, index + 1) - .join(" > ") - .trim(); - const previous = categories.slice(0, index).join(" > ").trim(); - const selected = selectedCategory.includes(current); - return ( - - selected && selectedCategory === current - ? setSelectedCategory(previous) - : setSelectedCategory(current) - } - icon={ - selected ? ( - - ) : ( - - ) - } - /> - ); - })} - - - )} - - {(username || categories) && tags && ( - - )} + {username && tags && } {tags && ( diff --git a/app/scripts/manage/ManagementApp.jsx b/app/scripts/manage/ManagementApp.jsx index bfe6318..9550e05 100644 --- a/app/scripts/manage/ManagementApp.jsx +++ b/app/scripts/manage/ManagementApp.jsx @@ -49,7 +49,6 @@ import { } from "@material-ui/icons"; import DashboardView from "./views/DashboardView"; -import CategoriesFilterView from "./views/CategoriesFilterView"; import KeywordsFilterView from "./views/KeywordsFilterView"; import UsersFilterView from "./views/UsersFilterView"; @@ -214,9 +213,6 @@ const ManagementAppMain = ({ darkMode, setDarkMode }) => { - - - diff --git a/app/scripts/manage/components/OptionsCard.jsx b/app/scripts/manage/components/OptionsCard.jsx index 4a68c81..726bbcc 100644 --- a/app/scripts/manage/components/OptionsCard.jsx +++ b/app/scripts/manage/components/OptionsCard.jsx @@ -27,6 +27,10 @@ const initialOptions = { pages: Object.keys(PAGES) .map((page) => [page, true]) .reduce((acc, val) => ((acc[val[0]] = val[1]), acc), {}), + placeholders: { + preventClick: true, + showFilterText: true, + }, showUpdatedPageOnUpdate: "patch", }; @@ -81,6 +85,17 @@ const OptionsCard = () => { showReloadRequired(); }; + const togglePlaceholderOption = (event) => { + setOptions({ + ...options, + placeholders: { + ...options.placeholders, + [event.target.name]: event.target.checked, + }, + }); + showReloadRequired(); + }; + const handleUpdatePageChange = (event) => { setOptions({ ...options, @@ -143,6 +158,40 @@ const OptionsCard = () => { )} + {options?.placeholders && ( + + + {browser.i18n.getMessage("Options_PlaceholderFunctionality_Header")} + + + {browser.i18n.getMessage("Options_PlaceholderFunctionality_HelpText")} + + + {Object.keys(options?.placeholders).map((key) => ( + + } + /> + ))} + + + )} + {options?.showUpdatedPageOnUpdate && ( { primary={browser.i18n.getMessage("SidebarLink_Keywords")} /> - - - - - - {/* diff --git a/app/scripts/manage/components/VirtualizedAutoComplete.jsx b/app/scripts/manage/components/VirtualizedAutoComplete.jsx deleted file mode 100644 index 9ba253c..0000000 --- a/app/scripts/manage/components/VirtualizedAutoComplete.jsx +++ /dev/null @@ -1,148 +0,0 @@ -/* eslint-disable react/prop-types */ -/* eslint-disable react/display-name */ -import React from "react"; -import { - useMediaQuery, - ListSubheader, - TextField, - Typography, - CircularProgress, -} from "@material-ui/core"; -import Autocomplete from "@material-ui/lab/Autocomplete"; -import { useTheme, makeStyles } from "@material-ui/core/styles"; -import { VariableSizeList } from "react-window"; -import parse from "autosuggest-highlight/parse"; -import match from "autosuggest-highlight/match"; -import { matchSorter } from "match-sorter"; - -const LISTBOX_PADDING = 8; // px - -const RenderRow = (props) => { - const { data, index, style } = props; - return React.cloneElement(data[index], { - style: { - ...style, - top: style.top + LISTBOX_PADDING, - }, - }); -}; - -const OuterElementContext = React.createContext({}); - -const OuterElementType = React.forwardRef((props, ref) => { - const outerProps = React.useContext(OuterElementContext); - return
; -}); - -// adapter for react-window -const VirtualizedListboxComponent = React.forwardRef((props, ref) => { - const { children, ...other } = props; - const itemData = React.Children.toArray(children); - const theme = useTheme(); - const smUp = useMediaQuery(theme.breakpoints.up("sm"), { noSsr: true }); - const itemCount = itemData.length; - const itemSize = smUp ? 36 : 48; - - const getChildSize = (child) => { - if (React.isValidElement(child) && child.type === ListSubheader) { - return 48; - } - - return itemSize; - }; - - const getHeight = () => { - if (itemCount > 8) { - return 8 * itemSize; - } - return itemData.map(getChildSize).reduce((a, b) => a + b, 0); - }; - - return ( -
- - getChildSize(itemData[index])} - overscanCount={5} - itemCount={itemCount} - > - {RenderRow} - - -
- ); -}); - -const useStyles = makeStyles({ - listbox: { - "& ul": { - padding: 0, - margin: 0, - }, - }, -}); - -export default function VirtualizedAutoComplete({ - label, - onChange, - error, - helperText, - ...props -}) { - const classes = useStyles(); - - return ( - - matchSorter(options, inputValue) - } - ListboxComponent={VirtualizedListboxComponent} - renderInput={(params) => ( - - {props.loading ? ( - - ) : null} - {params.InputProps.endAdornment} - - ), - }} - error={error} - helperText={helperText} - /> - )} - renderOption={(option, { inputValue }) => { - const matches = match(option, inputValue); - const parts = parse(option, matches); - - return ( - - {parts.map((part, index) => ( - - {part.text} - - ))} - - ); - }} - onChange={(_event, value) => onChange(value)} - {...props} - /> - ); -} diff --git a/app/scripts/manage/views/CategoriesFilterView.jsx b/app/scripts/manage/views/CategoriesFilterView.jsx deleted file mode 100644 index 2a61e4a..0000000 --- a/app/scripts/manage/views/CategoriesFilterView.jsx +++ /dev/null @@ -1,77 +0,0 @@ -/* eslint-disable react/display-name */ -/* eslint-disable react/prop-types */ -import React, { useEffect, useState } from "react"; -import { Grid } from "@material-ui/core"; -import VirtualizedAutoComplete from "../components/VirtualizedAutoComplete"; -import FilterTable from "../components/FilterTable"; -import { FETCH_CATEGORIES } from "../../constants/messages"; - -const ERROR_OPTION = browser.i18n.getMessage("CategoriesMenuErrorOption"); - -const CategoriesFilterView = () => { - const [loading, setLoading] = useState(false); - const [options, setOptions] = useState("options", []); - - const [categoryNameError, setCategoryNameError] = useState({ - error: false, - helperText: "", - }); - - useEffect(() => { - const loadOptions = async () => { - setLoading(true); - try { - const options = await browser.runtime.sendMessage({ - action: FETCH_CATEGORIES, - }); - setOptions(options); - } catch (error) { - console.error(error); - setOptions([ERROR_OPTION]); - } - setLoading(false); - }; - loadOptions(); - }, []); - - const columns = [ - { - title: browser.i18n.getMessage("Filter_Categories_PropTitle_Name"), - field: "name", - editComponent: (props) => ( - option === ERROR_OPTION} - label={browser.i18n.getMessage("CategoriesMenuLabel")} - noOptionsText={browser.i18n.getMessage("CategoriesMenuNoOptionsText")} - value={props.value} - onChange={props.onChange} - autoHighlight - disableListWrap - filterSelectedOptions - selectOnFocus - size="small" - loading={loading} - error={categoryNameError.error} - helperText={categoryNameError.helperText ?? ""} - /> - ), - required: true, - setError: setCategoryNameError, - }, - ]; - - return ( - - - - - - ); -}; - -export default CategoriesFilterView; diff --git a/app/scripts/manage/views/DashboardView.jsx b/app/scripts/manage/views/DashboardView.jsx index 874d6cc..0ac8a25 100644 --- a/app/scripts/manage/views/DashboardView.jsx +++ b/app/scripts/manage/views/DashboardView.jsx @@ -18,27 +18,20 @@ const DashboardView = () => { return ( - + - + - - - diff --git a/app/styles/content.css b/app/styles/content.css index c324fb3..4f6a10d 100644 --- a/app/styles/content.css +++ b/app/styles/content.css @@ -35,15 +35,17 @@ body#deviantART-v7 { /* === PLACEHOLDERS ===*/ -[da-filter-category], [da-filter-keyword], [da-filter-user] { position: relative !important; - pointer-events: none !important; visibility: visible !important; } -[data-hook="deviation_link"][da-filter-category], +body:not(.clickable-placeholders) [da-filter-keyword], +body:not(.clickable-placeholders) [da-filter-user] { + pointer-events: none !important; +} + [data-hook="deviation_link"][da-filter-keyword], [data-hook="deviation_link"][da-filter-user] { /* thumbnails on notification pages */ @@ -51,7 +53,6 @@ body#deviantART-v7 { position: absolute !important; } -[data-hook="deviation_std_thumb"] [data-hook="deviation_link"][da-filter-category], [data-hook="deviation_std_thumb"] [data-hook="deviation_link"][da-filter-keyword], [data-hook="deviation_std_thumb"] [data-hook="deviation_link"][da-filter-user] { /* thumbnails on browse/search pages, profile/group pages */ @@ -59,7 +60,6 @@ body#deviantART-v7 { position: absolute !important; } -[role="complementary"] [data-hook="deviation_link"][da-filter-category], [role="complementary"] [data-hook="deviation_link"][da-filter-keyword], [role="complementary"] [data-hook="deviation_link"][da-filter-user] { /* thumbnails in sidebar on individual deviation pages */ @@ -67,7 +67,6 @@ body#deviantART-v7 { position: relative !important; } -[da-filter-category]::before, [da-filter-keyword]::before, [da-filter-user]::before { /* the placeholder text and background, placed overtop the thumbnail */ @@ -92,7 +91,6 @@ body#deviantART-v7 { flex-direction: column-reverse; } -[da-filter-category]::after, [da-filter-keyword]::after, [da-filter-user]::after { /* the placeholder image ONLY, uses an SVG mask imitate programmatic color */ @@ -117,10 +115,6 @@ body#deviantART-v7 { -webkit-mask-size: 80% 50%; } -[da-filter-category]::before { - content: "__MSG_Placeholder_Category__: " attr(da-filter-category); -} - [da-filter-keyword]::before { content: "__MSG_Placeholder_Keyword__: " attr(da-filter-keyword); } @@ -138,6 +132,18 @@ body#deviantART-v7 { content: "__MSG_Placeholder_User__: " attr(data-username); } +body.hide-placeholder-text [da-filter-category]::before, +body.hide-placeholder-text [da-filter-keyword]::before, +body.hide-placeholder-text [da-filter-keyword][da-filter-keyword-attribute]::before, +body.hide-placeholder-text [da-filter-user]::before, +body.hide-placeholder-text [da-filter-user][data-username]:not([data-username=""])::before { + /* + when the placeholder text is hidden, the content property is still needed (but it should be empty), + as the `before` pseudo-element, which has the background that blocks out the thumbnail, won't render without it + */ + content: "" !important; +} + /* === METADATA STATUS/INDICATORS === */ /* TODO: make these optional? */ diff --git a/docs/_config.yml b/docs/_config.yml index 2c97c1a..9923393 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -3,7 +3,7 @@ remote_theme: pmarsceill/just-the-docs title: DeviantArt Filter email: rthaut@gmail.com description: >- - Have you ever want to block/filter deviations (a.k.a. submissions) while browsing DeviantArt? Well now you can! Simply install DeviantArt Filter in your web browser of choice and start filtering by user, keyword, and/or category. + Have you ever want to block/filter deviations (a.k.a. submissions) while browsing DeviantArt? Well now you can! Simply install DeviantArt Filter in your web browser of choice and start filtering by user and/or keyword. baseurl: "/deviantART-Filter" url: "https://rthaut.github.io" plugins: diff --git a/docs/pages/index.md b/docs/pages/index.md index b9e2d4f..ea35413 100644 --- a/docs/pages/index.md +++ b/docs/pages/index.md @@ -7,13 +7,13 @@ nav_order: 1 # DeviantArt Filter -DeviantArt Filter allows configurable filtering/removal of deviations by user, keyword, and/or category on DeviantArt. +DeviantArt Filter allows configurable filtering/removal of deviations by user and/or keyword on DeviantArt. * * * ## Overview -Have you ever want to block/filter deviations (a.k.a. submissions) while browsing DeviantArt? **Well now you can!** Simply [install DeviantArt Filter](#installation) in your web browser of choice and start filtering by user, keyword, and/or category. +Have you ever want to block/filter deviations (a.k.a. submissions) while browsing DeviantArt? **Well now you can!** Simply [install DeviantArt Filter](#installation) in your web browser of choice and start filtering by user and/or keyword. ![DeviantArt Filter Promotional Image](https://raw.githubusercontent.com/rthaut/deviantART-Filter/master/promo/Screenshot_1280x800.png) diff --git a/docs/pages/installed.md b/docs/pages/installed.md index 9c64c80..c919e22 100644 --- a/docs/pages/installed.md +++ b/docs/pages/installed.md @@ -7,7 +7,7 @@ nav_exclude: true # DeviantArt Filter Installed -🙏 **Thank you for installing DeviantArt Filter**, the browser extension that allows you to filter/block/hide deviations by user, keyword, and/or category on [DeviantArt](https://www.deviantart.com). +🙏 **Thank you for installing DeviantArt Filter**, the browser extension that allows you to filter/block/hide deviations by user and/or keyword on [DeviantArt](https://www.deviantart.com). * * * diff --git a/docs/pages/releases/v6.2.0.md b/docs/pages/releases/v6.2.0.md new file mode 100644 index 0000000..251a751 --- /dev/null +++ b/docs/pages/releases/v6.2.0.md @@ -0,0 +1,23 @@ +--- +layout: release +title: Version 6.2.0 +permalink: /releases/v6.2.0/ +parent: Version 6 +grand_parent: Releases +nav_order: 4 +--- + +# Version 6.2.0 *(September 18, 2021)* + +## New Features + +### New Features + +- New context menu on Deviation links to create a User filter directly +- New options for configuring the placeholders + - Leave filtered thumbnails clickable + - Hide the filter reason/type text on placeholders + +### Other + +- Removed Category filters, as [DeviantArt has basically deprecated categories](https://github.com/rthaut/deviantART-Filter/issues/153) diff --git a/docs/pages/screenshots.md b/docs/pages/screenshots.md index 166469a..94e22e1 100644 --- a/docs/pages/screenshots.md +++ b/docs/pages/screenshots.md @@ -20,7 +20,7 @@ nav_order: 4 |:---------- |:--------- | | ![Screenshot of the filter creation modal](https://raw.githubusercontent.com/rthaut/deviantART-Filter/master/screenshots/Create-Filter-Modal-Initial-Light.png) | ![Screenshot of the filter creation modal (using Dark Mode)](https://raw.githubusercontent.com/rthaut/deviantART-Filter/master/screenshots/Create-Filter-Modal-Initial-Dark.png) | -| ![Screenshot of the filter creation modal after selecting a category and some tags](https://raw.githubusercontent.com/rthaut/deviantART-Filter/master/screenshots/Create-Filter-Modal-Selected-Light.png) | ![Screenshot of the filter creation modal after selecting a category and some tags (using Dark Mode)](https://raw.githubusercontent.com/rthaut/deviantART-Filter/master/screenshots/Create-Filter-Modal-Selected-Dark.png) | +| ![Screenshot of the filter creation modal after selecting the user and some tags](https://raw.githubusercontent.com/rthaut/deviantART-Filter/master/screenshots/Create-Filter-Modal-Selected-Light.png) | ![Screenshot of the filter creation modal after selecting the user and some tags (using Dark Mode)](https://raw.githubusercontent.com/rthaut/deviantART-Filter/master/screenshots/Create-Filter-Modal-Selected-Dark.png) | ### Create Filter Modal - Results @@ -84,24 +84,6 @@ nav_order: 4 |:---------- |:--------- | | ![Screenshot of editing a keyword filter](https://raw.githubusercontent.com/rthaut/deviantART-Filter/master/screenshots/Keywords-Editing-Light.png) | ![Screenshot of editing a keyword filter (using Dark Mode)](https://raw.githubusercontent.com/rthaut/deviantART-Filter/master/screenshots/Keywords-Editing-Dark.png) | -* * * - -## Manage Categories - -*Screenshots from DeviantArt Filter v6.0.0.* -{: .fs-2 } - -|:---------- |:--------- | -| ![Screenshot of the filtered categories view](https://raw.githubusercontent.com/rthaut/deviantART-Filter/master/screenshots/Categories-Light.png) | ![Screenshot of the filtered categories view (using Dark Mode)](https://raw.githubusercontent.com/rthaut/deviantART-Filter/master/screenshots/Categories-Dark.png) | - -### Manage Categories - Editing a Filter - -*Screenshots from DeviantArt Filter v6.0.0.* -{: .fs-2 } - -|:---------- |:--------- | -| ![Screenshot of editing a category filter](https://raw.githubusercontent.com/rthaut/deviantART-Filter/master/screenshots/Categories-Editing-Light.png) | ![Screenshot of editing a category filter (using Dark Mode)](https://raw.githubusercontent.com/rthaut/deviantART-Filter/master/screenshots/Categories-Editing-Dark.png) | - diff --git a/docs/pages/usage.md b/docs/pages/usage.md index 10de48d..b53d305 100644 --- a/docs/pages/usage.md +++ b/docs/pages/usage.md @@ -32,20 +32,19 @@ You can quickly create filters for any deviation you see while browsing from a c 1. While browsing DeviantArt, right click on any thumbnail image or link to a deviation. 2. Click the "Create Filters from this Deviation" option. -3. Use the [form in the modal dialog]({{ '/screenshots#create-filter-modal' | absolute_url }}) that is displayed to create a user filter, a category filter, and/or keyword filters. +3. Use the [form in the modal dialog]({{ '/screenshots#create-filter-modal' | absolute_url }}) that is displayed to create a user filter and/or keyword filters. ### Creating Filters Through the Management Page For more advanced control of your filters, you should use the management page. -1. After opening the [Management Page]({{ '/screenshots#dashboard' | absolute_url }}), navigate to any of the Manage [Users]({{ '/screenshots#manage-users' | absolute_url }})/[Keywords]({{ '/screenshots#manage-keywords' | absolute_url }})/[Categories]({{ '/screenshots#manage-categories' | absolute_url }}) views. +1. After opening the [Management Page]({{ '/screenshots#dashboard' | absolute_url }}), navigate to any of the Manage [Users]({{ '/screenshots#manage-users' | absolute_url }})/[Keywords]({{ '/screenshots#manage-keywords' | absolute_url }}) views. 2. Use the table that is displayed to view all of your existing filters. - You can sort the table by clicking the heading of any column. - You can page through your filters using the pagination controls below the table. 3. To create a new filter, use the **plus icon (+)** above the table to the right of the search bar. - For users, enter their username. - For keywords, enter a single keyword (*no spaces*), then choose if the keyword should use wildcard matching by checking the wildcard checkbox. - - For categories, select the category path from the menu (you can type in the field to filter results). 4. To change an existing filter, like the **pencil icon (✎)** next to the filter you want to change. - Click the **check mark icon (✔)** to the left of the filter you are changing to **save** your change(s). - Click the **cross icon (❌)** next to the left of the filter you are changing to **discard** your change(s). diff --git a/package-lock.json b/package-lock.json index 3e87d91..48d2d4c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,9 +13,7 @@ "@material-ui/core": "^4.12.3", "@material-ui/icons": "^4.11.2", "@material-ui/lab": "^4.0.0-alpha.60", - "autosuggest-highlight": "^3.1.1", "lodash-es": "^4.17.21", - "match-sorter": "^6.3.1", "material-ui-confirm": "^2.1.3", "notistack": "^1.0.10", "react": "^17.0.2", @@ -23,7 +21,6 @@ "react-dropzone": "^11.4.0", "react-router-dom": "^5.3.0", "react-use": "^17.3.1", - "react-window": "^1.8.6", "semver": "^7.3.5" }, "devDependencies": { @@ -3184,14 +3181,6 @@ "node": ">=4" } }, - "node_modules/autosuggest-highlight": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/autosuggest-highlight/-/autosuggest-highlight-3.1.1.tgz", - "integrity": "sha512-MQ6GNIGMMZbeA5FlBLXXgkZEthysCdYNkMV4MahB2/qB/9cwBnVsePUPnIqkMuzjzclTtDa67xln7cgLDu2f/g==", - "dependencies": { - "diacritic": "0.0.2" - } - }, "node_modules/aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", @@ -5324,11 +5313,6 @@ "node": ">= 0.8.0" } }, - "node_modules/diacritic": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/diacritic/-/diacritic-0.0.2.tgz", - "integrity": "sha1-/CqIe1pbwKCoVPthTHwvIJBh7gQ=" - }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -8985,15 +8969,6 @@ "integrity": "sha512-k1dB2HNeaNyORco8ulVEhctyEGkKHb2YWAhDsxeFlW2nROIirsctBYzKwwS3Vza+sKTS1zO4Z+n9/+9WbGLIxQ==", "dev": true }, - "node_modules/match-sorter": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-6.3.1.tgz", - "integrity": "sha512-mxybbo3pPNuA+ZuCUhm5bwNkXrJTbsk5VWbR5wiwz/GC6LIiegBGn2w3O08UG/jdbYLinw51fSQ5xNU1U3MgBw==", - "dependencies": { - "@babel/runtime": "^7.12.5", - "remove-accents": "0.4.2" - } - }, "node_modules/material-ui-confirm": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/material-ui-confirm/-/material-ui-confirm-2.1.3.tgz", @@ -11006,22 +10981,6 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" }, - "node_modules/react-window": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/react-window/-/react-window-1.8.6.tgz", - "integrity": "sha512-8VwEEYyjz6DCnGBsd+MgkD0KJ2/OXFULyDtorIiTz+QzwoP94tBoA7CnbtyXMm+cCeAUER5KJcPtWl9cpKbOBg==", - "dependencies": { - "@babel/runtime": "^7.0.0", - "memoize-one": ">=3.1.1 <6" - }, - "engines": { - "node": ">8.0.0" - }, - "peerDependencies": { - "react": "^15.0.0 || ^16.0.0 || ^17.0.0", - "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0" - } - }, "node_modules/read-pkg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", @@ -11282,11 +11241,6 @@ "node": ">= 0.10.0" } }, - "node_modules/remove-accents": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.2.tgz", - "integrity": "sha1-CkPTqq4egNuRngeuJUsoXZ4ce7U=" - }, "node_modules/request": { "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", @@ -16908,14 +16862,6 @@ "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.2.tgz", "integrity": "sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==" }, - "autosuggest-highlight": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/autosuggest-highlight/-/autosuggest-highlight-3.1.1.tgz", - "integrity": "sha512-MQ6GNIGMMZbeA5FlBLXXgkZEthysCdYNkMV4MahB2/qB/9cwBnVsePUPnIqkMuzjzclTtDa67xln7cgLDu2f/g==", - "requires": { - "diacritic": "0.0.2" - } - }, "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", @@ -18617,11 +18563,6 @@ "integrity": "sha1-p2o+0YVb56ASu4rBbLgPPADcKPA=", "dev": true }, - "diacritic": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/diacritic/-/diacritic-0.0.2.tgz", - "integrity": "sha1-/CqIe1pbwKCoVPthTHwvIJBh7gQ=" - }, "dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -21535,15 +21476,6 @@ "integrity": "sha512-k1dB2HNeaNyORco8ulVEhctyEGkKHb2YWAhDsxeFlW2nROIirsctBYzKwwS3Vza+sKTS1zO4Z+n9/+9WbGLIxQ==", "dev": true }, - "match-sorter": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-6.3.1.tgz", - "integrity": "sha512-mxybbo3pPNuA+ZuCUhm5bwNkXrJTbsk5VWbR5wiwz/GC6LIiegBGn2w3O08UG/jdbYLinw51fSQ5xNU1U3MgBw==", - "requires": { - "@babel/runtime": "^7.12.5", - "remove-accents": "0.4.2" - } - }, "material-ui-confirm": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/material-ui-confirm/-/material-ui-confirm-2.1.3.tgz", @@ -23084,15 +23016,6 @@ } } }, - "react-window": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/react-window/-/react-window-1.8.6.tgz", - "integrity": "sha512-8VwEEYyjz6DCnGBsd+MgkD0KJ2/OXFULyDtorIiTz+QzwoP94tBoA7CnbtyXMm+cCeAUER5KJcPtWl9cpKbOBg==", - "requires": { - "@babel/runtime": "^7.0.0", - "memoize-one": ">=3.1.1 <6" - } - }, "read-pkg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", @@ -23304,11 +23227,6 @@ "commander": "^2.6.0" } }, - "remove-accents": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.2.tgz", - "integrity": "sha1-CkPTqq4egNuRngeuJUsoXZ4ce7U=" - }, "request": { "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", diff --git a/package.json b/package.json index 2db8739..15356e0 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "name": "deviantart-filter", "title": "DeviantArt Filter", - "version": "6.1.1", - "description": "Allows configurable filtering/removal of deviations by user, keyword, and/or category on DeviantArt", + "version": "6.2.0", + "description": "Allows configurable filtering/removal of deviations by user and/or keyword on DeviantArt", "author": "Ryan Thaut (http://ryanthaut.com)", "homepage": "https://github.com/rthaut/deviantART-Filter", "license": "GPL-3.0", @@ -39,9 +39,7 @@ "@material-ui/core": "^4.12.3", "@material-ui/icons": "^4.11.2", "@material-ui/lab": "^4.0.0-alpha.60", - "autosuggest-highlight": "^3.1.1", "lodash-es": "^4.17.21", - "match-sorter": "^6.3.1", "material-ui-confirm": "^2.1.3", "notistack": "^1.0.10", "react": "^17.0.2", @@ -49,7 +47,6 @@ "react-dropzone": "^11.4.0", "react-router-dom": "^5.3.0", "react-use": "^17.3.1", - "react-window": "^1.8.6", "semver": "^7.3.5" }, "devDependencies": { diff --git a/screenshots/Categories-Dark.png b/screenshots/Categories-Dark.png deleted file mode 100644 index e346a33..0000000 Binary files a/screenshots/Categories-Dark.png and /dev/null differ diff --git a/screenshots/Categories-Editing-Dark.png b/screenshots/Categories-Editing-Dark.png deleted file mode 100644 index f510566..0000000 Binary files a/screenshots/Categories-Editing-Dark.png and /dev/null differ diff --git a/screenshots/Categories-Editing-Light.png b/screenshots/Categories-Editing-Light.png deleted file mode 100644 index 00e8556..0000000 Binary files a/screenshots/Categories-Editing-Light.png and /dev/null differ diff --git a/screenshots/Categories-Light.png b/screenshots/Categories-Light.png deleted file mode 100644 index db6fbd0..0000000 Binary files a/screenshots/Categories-Light.png and /dev/null differ diff --git a/screenshots/Create-Filter-Modal-Initial-Dark.png b/screenshots/Create-Filter-Modal-Initial-Dark.png index d960dbe..96ab610 100644 Binary files a/screenshots/Create-Filter-Modal-Initial-Dark.png and b/screenshots/Create-Filter-Modal-Initial-Dark.png differ diff --git a/screenshots/Create-Filter-Modal-Initial-Light.png b/screenshots/Create-Filter-Modal-Initial-Light.png index aa77084..a148083 100644 Binary files a/screenshots/Create-Filter-Modal-Initial-Light.png and b/screenshots/Create-Filter-Modal-Initial-Light.png differ diff --git a/screenshots/Create-Filter-Modal-Results-Dark.png b/screenshots/Create-Filter-Modal-Results-Dark.png index 8591f4d..0ec5d71 100644 Binary files a/screenshots/Create-Filter-Modal-Results-Dark.png and b/screenshots/Create-Filter-Modal-Results-Dark.png differ diff --git a/screenshots/Create-Filter-Modal-Results-Light.png b/screenshots/Create-Filter-Modal-Results-Light.png index 32622ba..46d648d 100644 Binary files a/screenshots/Create-Filter-Modal-Results-Light.png and b/screenshots/Create-Filter-Modal-Results-Light.png differ diff --git a/screenshots/Create-Filter-Modal-Selected-Dark.png b/screenshots/Create-Filter-Modal-Selected-Dark.png index 5a0ef99..bf4f478 100644 Binary files a/screenshots/Create-Filter-Modal-Selected-Dark.png and b/screenshots/Create-Filter-Modal-Selected-Dark.png differ diff --git a/screenshots/Create-Filter-Modal-Selected-Light.png b/screenshots/Create-Filter-Modal-Selected-Light.png index c284559..a0eacda 100644 Binary files a/screenshots/Create-Filter-Modal-Selected-Light.png and b/screenshots/Create-Filter-Modal-Selected-Light.png differ diff --git a/screenshots/Dashboard-Dark.png b/screenshots/Dashboard-Dark.png index e0de7c7..9248ec7 100644 Binary files a/screenshots/Dashboard-Dark.png and b/screenshots/Dashboard-Dark.png differ diff --git a/screenshots/Dashboard-Import-Results-Dark.png b/screenshots/Dashboard-Import-Results-Dark.png index decc4a1..538ac6c 100644 Binary files a/screenshots/Dashboard-Import-Results-Dark.png and b/screenshots/Dashboard-Import-Results-Dark.png differ diff --git a/screenshots/Dashboard-Import-Results-Light.png b/screenshots/Dashboard-Import-Results-Light.png index ef5fbf1..534d145 100644 Binary files a/screenshots/Dashboard-Import-Results-Light.png and b/screenshots/Dashboard-Import-Results-Light.png differ diff --git a/screenshots/Dashboard-Light.png b/screenshots/Dashboard-Light.png index ac38868..6d33887 100644 Binary files a/screenshots/Dashboard-Light.png and b/screenshots/Dashboard-Light.png differ diff --git a/screenshots/Filter Modal Screenshots.psd b/screenshots/Filter Modal Screenshots.psd index c55208e..fb5cb5e 100644 Binary files a/screenshots/Filter Modal Screenshots.psd and b/screenshots/Filter Modal Screenshots.psd differ diff --git a/screenshots/Keywords-Dark.png b/screenshots/Keywords-Dark.png index e74740b..ac5d857 100644 Binary files a/screenshots/Keywords-Dark.png and b/screenshots/Keywords-Dark.png differ diff --git a/screenshots/Keywords-Editing-Dark.png b/screenshots/Keywords-Editing-Dark.png index 943389c..73d001c 100644 Binary files a/screenshots/Keywords-Editing-Dark.png and b/screenshots/Keywords-Editing-Dark.png differ diff --git a/screenshots/Keywords-Editing-Light.png b/screenshots/Keywords-Editing-Light.png index 2ffbff9..9700d82 100644 Binary files a/screenshots/Keywords-Editing-Light.png and b/screenshots/Keywords-Editing-Light.png differ diff --git a/screenshots/Keywords-Light.png b/screenshots/Keywords-Light.png index c2ffa8e..604249b 100644 Binary files a/screenshots/Keywords-Light.png and b/screenshots/Keywords-Light.png differ diff --git a/screenshots/Management Window Screenshots.psd b/screenshots/Management Window Screenshots.psd new file mode 100644 index 0000000..7734220 Binary files /dev/null and b/screenshots/Management Window Screenshots.psd differ diff --git a/screenshots/Screenshots.psd b/screenshots/Screenshots.psd deleted file mode 100644 index ba127ec..0000000 Binary files a/screenshots/Screenshots.psd and /dev/null differ diff --git a/screenshots/Users-Dark.png b/screenshots/Users-Dark.png index 9351371..fee256f 100644 Binary files a/screenshots/Users-Dark.png and b/screenshots/Users-Dark.png differ diff --git a/screenshots/Users-Editing-Dark.png b/screenshots/Users-Editing-Dark.png index b236364..03ad64c 100644 Binary files a/screenshots/Users-Editing-Dark.png and b/screenshots/Users-Editing-Dark.png differ diff --git a/screenshots/Users-Editing-Light.png b/screenshots/Users-Editing-Light.png index e7ef3bc..2700740 100644 Binary files a/screenshots/Users-Editing-Light.png and b/screenshots/Users-Editing-Light.png differ diff --git a/screenshots/Users-Light.png b/screenshots/Users-Light.png index f5e547c..76c4e83 100644 Binary files a/screenshots/Users-Light.png and b/screenshots/Users-Light.png differ diff --git a/screenshots/firefox-permissions-6.0.0.jpg b/screenshots/firefox-permissions-6.0.0.jpg new file mode 100644 index 0000000..6e990d3 Binary files /dev/null and b/screenshots/firefox-permissions-6.0.0.jpg differ