dev: DRY base64 app icons from streams

This commit is contained in:
KernelDeimos
2025-01-03 11:46:01 -05:00
parent 06a67a3b22
commit 63401f2c83
5 changed files with 38 additions and 30 deletions

View File

@@ -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

View File

@@ -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(',');

View File

@@ -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')}`;
}
}
}
};

View File

@@ -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 });

View File

@@ -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;
}));
}