From 63401f2c836a45ed6f14e3db78f14353b0726f30 Mon Sep 17 00:00:00 2001 From: KernelDeimos Date: Fri, 3 Jan 2025 11:46:01 -0500 Subject: [PATCH] dev: DRY base64 app icons from streams --- src/backend/src/helpers.js | 9 +------ .../src/modules/apps/AppIconService.js | 8 +++++- .../src/modules/apps/lib/IconResult.js | 27 +++++++++++++++++++ src/backend/src/om/entitystorage/AppES.js | 7 ++--- src/backend/src/routers/get-launch-apps.js | 17 +----------- 5 files changed, 38 insertions(+), 30 deletions(-) create mode 100644 src/backend/src/modules/apps/lib/IconResult.js diff --git a/src/backend/src/helpers.js b/src/backend/src/helpers.js index 81749042..0b38c940 100644 --- a/src/backend/src/helpers.js +++ b/src/backend/src/helpers.js @@ -1539,14 +1539,7 @@ async function get_taskbar_items(user, { icon_size, no_icons } = {}) { size: icon_size, }); - if ( icon_result.data_url ) { - item.icon = icon_result.data_url; - } else { - const buffer = await stream_to_buffer(icon_result.stream); - const resp_data_url = `data:${icon_result.mime};base64,${buffer.toString('base64')}`; - - item.icon = resp_data_url; - } + item.icon = await icon_result.get_data_url(); } // add to final object diff --git a/src/backend/src/modules/apps/AppIconService.js b/src/backend/src/modules/apps/AppIconService.js index ac410f83..3578dd6b 100644 --- a/src/backend/src/modules/apps/AppIconService.js +++ b/src/backend/src/modules/apps/AppIconService.js @@ -10,6 +10,7 @@ const BaseService = require("../../services/BaseService.js"); const ICON_SIZES = [16,32,64,128,256,512]; const DEFAULT_APP_ICON = require('./default-app-icon.js'); +const IconResult = require("./lib/IconResult.js"); /** * AppIconService handles icon generation and serving for apps. @@ -95,7 +96,12 @@ class AppIconService extends BaseService { })); } - async get_icon_stream ({ app_icon, app_uid, size, tries = 0 }) { + async get_icon_stream (params) { + const result = await this.get_icon_stream_(params); + return new IconResult(result); + } + + async get_icon_stream_ ({ app_icon, app_uid, size, tries = 0 }) { // If there is an icon provided, and it's an SVG, we'll just return it if ( app_icon ) { const [metadata, data] = app_icon.split(','); diff --git a/src/backend/src/modules/apps/lib/IconResult.js b/src/backend/src/modules/apps/lib/IconResult.js new file mode 100644 index 00000000..c26210df --- /dev/null +++ b/src/backend/src/modules/apps/lib/IconResult.js @@ -0,0 +1,27 @@ +const { stream_to_buffer } = require("../../../util/streamutil"); + +module.exports = class IconResult { + constructor (o) { + Object.assign(this, o); + } + + async get_data_url () { + if ( this.data_url ) { + return this.data_url; + } else { + try { + const buffer = await stream_to_buffer(this.stream); + return `data:${this.mime};base64,${buffer.toString('base64')}`; + } catch (e) { + const svc_error = Context.get(undefined, { + allow_fallback: true, + }).get('services').get('error'); + svc_error.report('IconResult:get_data_url', { + source: e, + }); + // TODO: broken image icon here + return `data:image/png;base64,${Buffer.from([]).toString('base64')}`; + } + } + } +}; diff --git a/src/backend/src/om/entitystorage/AppES.js b/src/backend/src/om/entitystorage/AppES.js index b8d6e26b..dfe0d0be 100644 --- a/src/backend/src/om/entitystorage/AppES.js +++ b/src/backend/src/om/entitystorage/AppES.js @@ -314,15 +314,12 @@ class AppES extends BaseES { if ( icon_size ) { const svc_appIcon = this.context.get('services').get('app-icon'); try { - const { stream, mime } = await svc_appIcon.get_icon_stream({ + const icon_result = await svc_appIcon.get_icon_stream({ app_uid: await entity.get('uid'), app_icon: await entity.get('icon'), size: icon_size, }); - if ( ! stream ) throw Error('no stream'); - const buffer = await stream_to_buffer(stream); - const data_url = `data:${mime};base64,${buffer.toString('base64')}`; - await entity.set('icon', data_url); + await entity.set('icon', await icon_result.get_data_url()); } catch (e) { const svc_error = this.context.get('services').get('error-service'); svc_error.report('AppES:read_transform', { source: e }); diff --git a/src/backend/src/routers/get-launch-apps.js b/src/backend/src/routers/get-launch-apps.js index 99dd9475..57b55d71 100644 --- a/src/backend/src/routers/get-launch-apps.js +++ b/src/backend/src/routers/get-launch-apps.js @@ -33,22 +33,7 @@ const iconify_apps = async (context, { apps, size }) => { size: size, }); - if ( icon_result.data_url ) { - app.icon = icon_result.data_url; - return app; - } - - try { - const buffer = await stream_to_buffer(icon_result.stream); - const resp_data_url = `data:${icon_result.mime};base64,${buffer.toString('base64')}`; - - app.icon = resp_data_url; - } catch (e) { - const svc_error = context.services.get('error'); - svc_error.report('get-launch-apps:icon-stream', { - source: e, - }); - } + app.icon = await icon_result.get_data_url(); return app; })); }