From a978c96987f2bf957c80675137b89622796420cf Mon Sep 17 00:00:00 2001 From: Anton Kastritskiy Date: Fri, 20 Oct 2023 07:23:34 -0700 Subject: [PATCH] large fb icons only, no density Summary: Currently we download a bunch of FB icons and we normally use the smallest one available. In this diff I change the download logic so we try to download from the largest to the smallest icon and use the first one available. One the client we no longer provide the icon of the same size that is requested, instead we provide the only one we have which will typically be larger than needed. This is a good thing because 1. flipper is a local application and we do not need to worry about icons take up broadband and downloading 2. People have high density displayed I also stopped using density(rest of related code removed in the next diff) for icons as it the icons themselves did not support it. Reviewed By: lblasa Differential Revision: D50495194 fbshipit-source-id: f569c2f3b8ee424a67c6d21136e7e113868b8f6a --- desktop/.gitignore | 1 + .../app/src/utils/__tests__/icons.node.tsx | 6 +- desktop/app/src/utils/icons.tsx | 7 +- .../src/initializeRenderHost.tsx | 2 +- .../src/initializeRenderHost.tsx | 2 +- .../src/ui/components/Glyph.tsx | 2 +- desktop/flipper-ui-core/src/utils/icons.tsx | 6 +- desktop/scripts/build-icons.tsx | 46 +- desktop/static/icons.json | 1057 ++++++----------- 9 files changed, 406 insertions(+), 723 deletions(-) diff --git a/desktop/.gitignore b/desktop/.gitignore index 11851aab5..a23584694 100644 --- a/desktop/.gitignore +++ b/desktop/.gitignore @@ -12,3 +12,4 @@ tsc-error.log /flipper-server/static/ /static/flipper-server-log* /static/.audit.json +/static/icons/*_d.png diff --git a/desktop/app/src/utils/__tests__/icons.node.tsx b/desktop/app/src/utils/__tests__/icons.node.tsx index 7e60a42b7..0e86020b7 100644 --- a/desktop/app/src/utils/__tests__/icons.node.tsx +++ b/desktop/app/src/utils/__tests__/icons.node.tsx @@ -21,7 +21,7 @@ test('filled icons get correct local path', () => { size: 12, density: 2, }); - expect(iconPath).toBe(path.join('icons', 'star-filled-12@2x.png')); + expect(iconPath).toBe(path.join('icons', 'star-filled_d.png')); }); test('outline icons get correct local path', () => { @@ -31,7 +31,7 @@ test('outline icons get correct local path', () => { size: 12, density: 2, }); - expect(iconPath).toBe(path.join('icons', 'star-outline-12@2x.png')); + expect(iconPath).toBe(path.join('icons', 'star-outline_d.png')); }); test('filled icons get correct URL', async () => { @@ -51,7 +51,7 @@ test('filled icons get correct URL', async () => { expect(localUrl).toBe(iconUrl); // ... let's mock a file - const iconPath = path.join(staticPath, 'icons', 'star-filled-12@2x.png'); + const iconPath = path.join(staticPath, 'icons', 'star-filled_d.png'); try { await fs.promises.writeFile( iconPath, diff --git a/desktop/app/src/utils/icons.tsx b/desktop/app/src/utils/icons.tsx index c8993a3b4..01fe1389f 100644 --- a/desktop/app/src/utils/icons.tsx +++ b/desktop/app/src/utils/icons.tsx @@ -23,7 +23,7 @@ let _icons: Icons | undefined; function getIconsSync(staticPath: string): Icons { return ( - _icons! ?? + _icons ?? (_icons = JSON.parse( fs.readFileSync(path.join(staticPath, 'icons.json'), {encoding: 'utf8'}), )) @@ -31,10 +31,7 @@ function getIconsSync(staticPath: string): Icons { } export function buildLocalIconPath(icon: Icon) { - return path.join( - 'icons', - `${icon.name}-${icon.variant}-${icon.size}@${icon.density}x.png`, - ); + return path.join('icons', `${icon.name}-${icon.variant}_d.png`); } export function getLocalIconUrl( diff --git a/desktop/flipper-server-companion/src/initializeRenderHost.tsx b/desktop/flipper-server-companion/src/initializeRenderHost.tsx index a35192397..d88936cbf 100644 --- a/desktop/flipper-server-companion/src/initializeRenderHost.tsx +++ b/desktop/flipper-server-companion/src/initializeRenderHost.tsx @@ -74,7 +74,7 @@ export function initializeRenderHost( }, getLocalIconUrl(icon, url) { if (isProduction()) { - return `icons/${icon.name}-${icon.variant}-${icon.size}@${icon.density}x.png`; + return `icons/${icon.name}-${icon.variant}_d.png`; } return url; }, diff --git a/desktop/flipper-ui-browser/src/initializeRenderHost.tsx b/desktop/flipper-ui-browser/src/initializeRenderHost.tsx index 00ab059e6..1008f9fd2 100644 --- a/desktop/flipper-ui-browser/src/initializeRenderHost.tsx +++ b/desktop/flipper-ui-browser/src/initializeRenderHost.tsx @@ -203,7 +203,7 @@ export function initializeRenderHost( }, getLocalIconUrl(icon, url) { if (isProduction()) { - return `icons/${icon.name}-${icon.variant}-${icon.size}@${icon.density}x.png`; + return `icons/${icon.name}-${icon.variant}_d.png`; } return url; }, diff --git a/desktop/flipper-ui-core/src/ui/components/Glyph.tsx b/desktop/flipper-ui-core/src/ui/components/Glyph.tsx index dd6208cd9..17eadd84f 100644 --- a/desktop/flipper-ui-core/src/ui/components/Glyph.tsx +++ b/desktop/flipper-ui-core/src/ui/components/Glyph.tsx @@ -11,7 +11,7 @@ import React from 'react'; import styled from '@emotion/styled'; import {getIconURL} from '../../utils/icons'; -export type IconSize = 8 | 10 | 12 | 16 | 18 | 20 | 24 | 28 | 32; +export type IconSize = 8 | 10 | 12 | 16 | 18 | 20 | 24 | 28 | 32 | 48; const ColoredIconBlack = styled.img<{size: number}>(({size}) => ({ height: size, diff --git a/desktop/flipper-ui-core/src/utils/icons.tsx b/desktop/flipper-ui-core/src/utils/icons.tsx index da866bf9d..8b387f9eb 100644 --- a/desktop/flipper-ui-core/src/utils/icons.tsx +++ b/desktop/flipper-ui-core/src/utils/icons.tsx @@ -10,8 +10,8 @@ import {getRenderHostInstance} from 'flipper-frontend-core'; import {IconSize} from '../ui/components/Glyph'; -const AVAILABLE_SIZES: IconSize[] = [8, 10, 12, 16, 18, 20, 24, 28, 32]; -const DENSITIES = [1, 2, 3]; +const AVAILABLE_SIZES: IconSize[] = [8, 10, 12, 16, 18, 20, 24, 28, 32, 48]; +const DENSITIES = [1, 1.5, 2, 3, 4]; export type Icon = { name: string; @@ -58,7 +58,7 @@ function normalizeIcon(icon: Icon): Icon { }; } -export function getPublicIconUrl({name, variant, size, density}: Icon) { +export function getPublicIconUrl({name, variant, size}: Icon) { return `https://facebook.com/images/assets_DO_NOT_HARDCODE/facebook_icons/${name}_${variant}_${size}.png`; } diff --git a/desktop/scripts/build-icons.tsx b/desktop/scripts/build-icons.tsx index bda85ff0d..da76bf060 100644 --- a/desktop/scripts/build-icons.tsx +++ b/desktop/scripts/build-icons.tsx @@ -13,7 +13,7 @@ import fetch from '@adobe/node-fetch-retry'; // eslint-disable-next-line node/no-extraneous-import import type {Icon} from 'flipper-ui-core'; -const AVAILABLE_SIZES: Icon['size'][] = [8, 10, 12, 16, 18, 20, 24, 28, 32]; +const AVAILABLE_SIZES: Icon['size'][] = [8, 10, 12, 16, 18, 20, 24, 28, 32, 48]; export type Icons = { [key: string]: Icon['size'][]; @@ -32,38 +32,26 @@ function getIconPartsFromName(icon: string): { } export async function downloadIcons(buildFolder: string) { - const icons: Icons = JSON.parse( + const icons: string[] = JSON.parse( await fs.promises.readFile(path.join(buildFolder, 'icons.json'), { encoding: 'utf8', }), ); - const iconURLs = Object.entries(icons).reduce( - (acc, [entryName, sizes]) => { - const {trimmedName: name, variant} = getIconPartsFromName(entryName); - acc.push( - // get icons in @1x and @2x - ...sizes.map((size) => ({name, variant, size, density: 1})), - ...sizes.map((size) => ({name, variant, size, density: 2})), - ...sizes.map((size) => ({name, variant, size, density: 3})), - ); - return acc; - }, - [], - ); + const iconURLs: Pick[] = icons.map((rawName) => { + const {trimmedName: name, variant} = getIconPartsFromName(rawName); + return {name, variant}; + }); + // Download first largest instance of each icon await Promise.all( iconURLs.map(async (icon) => { - const sizeIndex = AVAILABLE_SIZES.indexOf(icon.size); - if (sizeIndex === -1) { - throw new Error('Size unavailable: ' + icon.size); - } - const sizesToTry = AVAILABLE_SIZES.slice(sizeIndex); + const sizesToTry = [...AVAILABLE_SIZES]; while (sizesToTry.length) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const size = sizesToTry.shift()!; + const size = sizesToTry.pop()!; - const url = getPublicIconUrl({...icon, size}); + const url = getPublicIconUrl({...(icon as Icon), size}); const res = await fetch(url); if (res.status !== 200) { // console.log( @@ -89,21 +77,21 @@ export async function downloadIcons(buildFolder: string) { console.error( `Could not download the icon ${JSON.stringify( icon, - )} from ${getPublicIconUrl(icon)}, didn't find any matching size`, + )} from ${getPublicIconUrl({ + ...icon, + size: AVAILABLE_SIZES[AVAILABLE_SIZES.length - 1], + } as Icon)}, didn't find any matching size`, ); }), ); } // should match flipper-ui-core/src/utils/icons.tsx -export function getPublicIconUrl({name, variant, size, density}: Icon) { +export function getPublicIconUrl({name, variant, size}: Icon) { return `https://facebook.com/images/assets_DO_NOT_HARDCODE/facebook_icons/${name}_${variant}_${size}.png`; } // should match app/src/utils/icons.tsx -function buildLocalIconPath(icon: Icon) { - return path.join( - 'icons', - `${icon.name}-${icon.variant}-${icon.size}@${icon.density}x.png`, - ); +function buildLocalIconPath(icon: Pick) { + return path.join('icons', `${icon.name}-${icon.variant}_d.png`); } diff --git a/desktop/static/icons.json b/desktop/static/icons.json index 9719f74e0..8f189d9e2 100644 --- a/desktop/static/icons.json +++ b/desktop/static/icons.json @@ -1,680 +1,377 @@ -{ - "accessibility": [ - 16, - 20 - ], - "app-dailies": [ - 12 - ], - "app-react": [ - 12, - 16 - ], - "apps": [ - 12, - 16 - ], - "arrow-right": [ - 12, - 16 - ], - "bell-null-outline": [ - 24 - ], - "bell-null": [ - 12 - ], - "bell": [ - 12 - ], - "bird": [ - 12, - 16 - ], - "borders": [ - 16 - ], - "box": [ - 12, - 24 - ], - "brush-paint": [ - 12, - 16 - ], - "bug": [ - 12, - 20 - ], - "building-city": [ - 12, - 16 - ], - "camcorder": [ - 12, - 16 - ], - "camera": [ - 12, - 16 - ], - "caution-octagon": [ - 12, - 16, - 20 - ], - "caution-triangle": [ - 12, - 16, - 20, - 24 - ], - "caution": [ - 16, - 24 - ], - "checkmark": [ - 16 - ], - "chevron-down-outline": [ - 10 - ], - "chevron-down": [ - 12, - 16, - 8 - ], - "chevron-left": [ - 12, - 16 - ], - "chevron-right": [ - 8, - 12, - 16 - ], - "chevron-up": [ - 12, - 16, - 8 - ], - "compose": [ - 12, - 16 - ], - "copy": [ - 12, - 16 - ], - "cross-circle": [ - 12, - 16, - 24 - ], - "cross": [ - 12, - 16 - ], - "dashboard-outline": [ - 24 - ], - "dashboard": [ - 12, - 16 - ], - "data-table": [ - 12, - 16 - ], - "desktop": [ - 12 - ], - "directions": [ - 12, - 16 - ], - "dots-3-circle-outline": [ - 16 - ], - "download": [ - 16 - ], - "face-unhappy-outline": [ - 24 - ], - "first-aid": [ - 12 - ], - "flash-default": [ - 12, - 16 - ], - "info-circle": [ - 12, - 16, - 24 - ], - "internet": [ - 12, - 16 - ], - "life-event-major": [ - 16 - ], - "magic-wand": [ - 12, - 16, - 20 - ], - "magnifying-glass": [ - 16, - 20, - 24 - ], - "messages": [ - 12, - 16 - ], - "minus-circle": [ - 12 - ], - "mobile-engagement": [ - 16 - ], - "mobile": [ - 12, - 16, - 32 - ], - "network": [ - 12, - 16 - ], - "news-feed": [ - 12, - 16 - ], - "pause": [ - 16 - ], - "posts": [ - 20 - ], - "power": [ - 16 - ], - "profile": [ - 12, - 16 - ], - "question-circle-outline": [ - 16 - ], - "question-circle": [ - 12, - 16, - 20 - ], - "question": [ - 16 - ], - "refresh-left": [ - 16 - ], - "rocket": [ - 12, - 16, - 20 - ], - "settings": [ - 12 - ], - "share-external": [ - 12, - 16 - ], - "share": [ - 16 - ], - "star-outline": [ - 12, - 16, - 24 - ], - "star-slash": [ - 16 - ], - "star": [ - 12, - 16, - 24 - ], - "stop-playback": [ - 12, - 16 - ], - "stop": [ - 16, - 24 - ], - "target": [ - 12, - 16 - ], - "thought-bubble": [ - 12, - 16 - ], - "tools": [ - 12, - 16, - 20 - ], - "translate": [ - 12, - 16 - ], - "trash-outline": [ - 16 - ], - "trash": [ - 12, - 16 - ], - "tree": [ - 12, - 16 - ], - "trending": [ - 12, - 16 - ], - "triangle-down": [ - 12, - 16, - 20 - ], - "triangle-right": [ - 12 - ], - "underline": [ - 12, - 16 - ], - "washing-machine": [ - 12, - 16 - ], - "watch-tv": [ - 12, - 16 - ], - "gears-two": [ - 16 - ], - "info-cursive": [ - 16 - ], - "on-this-day": [ - 12 - ], - "zoom-out": [ - 16 - ], - "zoom-in": [ - 16 - ], - "fast-forward": [ - 16 - ], - "draft-outline": [ - 16 - ], - "gradient": [ - 16 - ], - "crop": [ - 16 - ], - "play": [ - 16 - ], - "cross-outline": [ - 16 - ], - "messenger-code": [ - 12, - 16 - ], - "book": [ - 12 - ], - "list-arrow-up": [ - 12, - 16 - ], - "cat": [ - 12, - 16 - ], - "duplicate": [ - 12, - 16 - ], - "profile-circle-outline": [ - 16 - ], - "card-person": [ - 12, - 16 - ], - "pencil-outline": [ - 16 - ], - "code": [ - 12, - 16, - 20 - ], - "undo-outline": [ - 16 - ], - "checkmark-circle-outline": [ - 24 - ], - "target-outline": [ - 16, - 24 - ], - "internet-outline": [ - 24, - 32 - ], - "profile-outline": [ - 32 - ], - "app-react-outline": [ - 16 - ], - "send-outline": [ - 16 - ], - "paper-stack": [ - 12, - 16 - ], - "weather-cold": [ - 12, - 16 - ], - "mobile-cross": [ - 16 - ], - "database-arrow-left": [ - 12 - ], - "plus-circle-outline": [ - 16 - ], - "arrows-circle": [ - 12 - ], - "navicon": [ - 12 - ], - "paper-fold-text": [ - 16 - ], - "marketplace": [ - 12, - 16 - ], - "workflow": [ - 12 - ], - "sankey-diagram": [ - 12, - 16 - ], - "media-stack": [ - 16 - ], - "question-hexagon": [ - 16 - ], - "briefcase": [ - 16 - ], - "business-briefcase": [ - 16 - ], - "log": [ - 12, - 16 - ], - "triangle-up": [ - 16, - 20 - ], - "checkmark-circle": [ - 12, - 20 - ], - "circle": [ - 12 - ], - "comment-swish": [ - 16 - ], - "direct": [ - 16 - ], - "plus": [ - 16 - ], - "scuba": [ - 12, - 16 - ], - "line-chart": [ - 12, - 16 - ], - "caution-circle": [ - 12, - 24 - ], - "megaphone": [ - 12, - 16 - ], - "wireless": [ - 16 - ], - "cup-outline": [ - 24 - ], - "unicorn": [ - 20 - ], - "turtle": [ - 20 - ], - "sushi": [ - 12 - ], - "arrows-up-down": [ - 16 - ], - "style-effects": [ - 16 - ], - "stopwatch": [ - 16 - ], - "database": [ - 16 - ], - "bar-chart": [ - 16 - ], - "augmented-reality": [ - 16 - ], - "app-flash": [ - 16 - ], - "sample-lo": [ - 20 - ], - "point": [ - 20 - ], - "eye": [ - 16 - ], - "send": [ - 16 - ], - "refresh-right": [ - 12, - 16 - ], - "hourglass": [ - 16 - ], - "mobile-outline": [ - 16, - 24 - ], - "bookmark-outline": [ - 16 - ], - "app-facebook-f-outline": [ - 24 - ], - "app-messenger-outline": [ - 24 - ], - "app-instagram-outline": [ - 24 - ], - "app-whatsapp-outline": [ - 24 - ], - "app-workplace-outline": [ - 24 - ], - "app-work-chat-outline": [ - 24 - ], - "sample-hi": [ - 20 - ], - "dog": [ - 12, - 16 - ], - "hub": [ - 16 - ], - "upload": [ - 16 - ], - "list-gear-outline": [ - 24 - ], - "app-apple-outline": [ - 24 - ], - "app-microsoft-windows": [ - 24 - ], - "box-outline": [ - 24 - ], - "differential": [ - 16 - ], - "raincloud": [ - 16 - ], - "app-microsoft-windows-outline": [ - 24 - ], - "camcorder-live": [ - 16 - ], - "plumbing": [ - 16 - ], - "app-facebook-circle": [ - 16 - ], - "link": [ - 16 - ], - "commercial-break-usd": [ - 16 - ], - "friends-engagement": [ - 16 - ], - "app-cms": [ - 16 - ], - "caution-triangle-outline": [ - 24 - ], - "bird-flying": [ - 16 - ], - "arrows-left-right": [ - 16 - ], - "grid-9": [ - 16 - ], - "stethoscope": [ - 16 - ], - "friend-except": [ - 16 - ], - "app-instagram": [ - 16 - ], - "nav-magnifying-glass": [ - 16 - ], - "list-arrow-down": [ - 16 - ], - "photo-arrows-left-right": [ - 16 - ], - "badge": [ - 16 - ], - "square-ruler": [ - 16 - ], - "phone": [ - 16 - ], - "app-horizon-assets": [ - 16 - ], - "app-bloks": [ - 16 - ], - "settings-internal": [ - 16 - ], - "weather-thunder-outline": [ - 16 - ], - "weather-thunder": [ - 16 - ] -} +[ + "accessibility", + "app-dailies", + "app-react", + "apps", + "arrow-right", + "bell-null-outline", + "bell-null", + "bell", + "bird", + "borders", + "box", + "brush-paint", + "bug", + "building-city", + + "camcorder", + + "camera", + + "caution-octagon", + + "caution-triangle", + + "caution", + + "checkmark", + + "chevron-down-outline", + + "chevron-down", + + "chevron-left", + + "chevron-right", + + "chevron-up", + + "compose", + + "copy", + + "cross-circle", + + "cross", + + "dashboard-outline", + + "dashboard", + + "data-table", + + "desktop", + + "directions", + + "dots-3-circle-outline", + + "download", + + "face-unhappy-outline", + + "first-aid", + + "flash-default", + + "info-circle", + + "internet", + + "life-event-major", + + "magic-wand", + + "magnifying-glass", + + "messages", + + "minus-circle", + + "mobile-engagement", + + "mobile", + + "network", + + "news-feed", + + "pause", + + "posts", + + "power", + + "profile", + + "question-circle-outline", + + "question-circle", + + "question", + + "refresh-left", + + "rocket", + + "settings", + + "share-external", + + "share", + + "star-outline", + + "star-slash", + + "star", + + "stop-playback", + + "stop", + + "target", + + "thought-bubble", + + "tools", + + "translate", + + "trash-outline", + + "trash", + + "tree", + + "trending", + + "triangle-down", + + "triangle-right", + + "underline", + + "washing-machine", + + "watch-tv", + + "gears-two", + + "info-cursive", + + "on-this-day", + + "zoom-out", + + "zoom-in", + + "fast-forward", + + "draft-outline", + + "gradient", + + "crop", + + "play", + + "cross-outline", + + "messenger-code", + + "book", + + "list-arrow-up", + + "cat", + + "duplicate", + + "profile-circle-outline", + + "card-person", + + "pencil-outline", + + "code", + + "undo-outline", + + "checkmark-circle-outline", + + "target-outline", + + "internet-outline", + + "profile-outline", + + "app-react-outline", + + "send-outline", + + "paper-stack", + + "weather-cold", + + "mobile-cross", + + "database-arrow-left", + + "plus-circle-outline", + + "arrows-circle", + + "navicon", + + "paper-fold-text", + + "marketplace", + + "workflow", + + "sankey-diagram", + + "media-stack", + + "question-hexagon", + + "briefcase", + + "business-briefcase", + + "log", + + "triangle-up", + + "checkmark-circle", + + "circle", + + "comment-swish", + + "direct", + + "plus", + + "scuba", + + "line-chart", + + "caution-circle", + + "megaphone", + + "wireless", + + "cup-outline", + + "unicorn", + + "turtle", + + "sushi", + + "arrows-up-down", + + "style-effects", + + "stopwatch", + + "database", + + "bar-chart", + + "augmented-reality", + + "app-flash", + + "sample-lo", + + "point", + + "eye", + + "send", + + "refresh-right", + + "hourglass", + + "mobile-outline", + + "bookmark-outline", + + "app-facebook-f-outline", + + "app-messenger-outline", + + "app-instagram-outline", + + "app-whatsapp-outline", + + "app-workplace-outline", + + "app-work-chat-outline", + + "sample-hi", + + "dog", + + "hub", + + "upload", + + "list-gear-outline", + + "app-apple-outline", + + "app-microsoft-windows", + + "box-outline", + + "differential", + + "raincloud", + + "app-microsoft-windows-outline", + + "camcorder-live", + + "plumbing", + + "app-facebook-circle", + + "link", + + "commercial-break-usd", + + "friends-engagement", + + "app-cms", + + "caution-triangle-outline", + + "bird-flying", + + "arrows-left-right", + + "grid-9", + + "stethoscope", + + "friend-except", + + "app-instagram", + + "nav-magnifying-glass", + + "list-arrow-down", + + "photo-arrows-left-right", + + "badge", + + "square-ruler", + + "phone", + + "app-horizon-assets", + + "app-bloks", + + "settings-internal", + + "weather-thunder-outline", + "weather-thunder" +]