dev: create pre-sized icons for apps

This commit is contained in:
KernelDeimos committed 2024-12-17 12:57:03 -05:00
1 parent 905be23854
commit 20d27d59bf
7 files changed
+543 -24

No files matched your search

+3
View File
@@ -355,6 +355,9 @@ const install = async ({ services, app, useapi, modapi }) => {
const { WSPushService } = require('./services/WSPushService');
services.registerService('__event-push-ws', WSPushService);
const { AppIconService } = require('./services/AppIconService');
services.registerService('app-icon', AppIconService);
}
const install_legacy = async ({ services }) => {
@@ -301,7 +301,7 @@ class HLWrite extends HLFilesystemOperation {
this.checkpoint('before thumbnail');
let thumbnail_promise = new TeePromise();
if ( await destination.isAppDataDirectory() ) {
if ( await destination.isAppDataDirectory() || values.no_thumbnail ) {
thumbnail_promise.resolve(undefined);
} else (async () => {
const reason = await (async () => {
+17
View File
@@ -129,6 +129,23 @@ class AppES extends BaseES {
await this.db.write(stmt, rows.flat());
}
const has_new_icon =
( ! extra.old_entity ) || (
await entity.get('icon') !== await extra.old_entity.get('icon')
);
if ( has_new_icon ) {
const svc_event = this.context.get('services').get('event');
const event = {
app_uid: await entity.get('uid'),
data_url: await entity.get('icon'),
};
await svc_event.emit('app.new-icon', event);
if ( event.url ) {
await entity.set('icon')
}
}
// Associate app with subdomain (if applicable)
if ( subdomain_id ) {
await this.db.write(
@@ -0,0 +1,88 @@
const { HLWrite } = require("../filesystem/hl_operations/hl_write");
const { LLMkdir } = require("../filesystem/ll_operations/ll_mkdir");
const { NodePathSelector, NodeChildSelector, RootNodeSelector } = require("../filesystem/node/selectors");
const { buffer_to_stream } = require("../util/streamutil");
const BaseService = require("./BaseService");
const ICON_SIZES = [16,32,64,128,256,512];
class AppIconService extends BaseService {
static MODULES = {
sharp: require('sharp'),
}
async ['__on_user.system-user-ready'] () {
const svc_su = this.services.get('su');
const svc_fs = this.services.get('filesystem');
const svc_user = this.services.get('user');
const dir_system = await svc_user.get_system_dir();
// Ensure app icons directory exists
const dir_app_icons = await svc_fs.node(
new NodePathSelector('/system/app_icons')
);
if ( ! await dir_app_icons.exists() ) {
const ll_mkdir = new LLMkdir();
await ll_mkdir.run({
parent: dir_system,
name: 'app_icons',
actor: await svc_su.get_system_actor(),
});
}
// Listen for new app icons
const svc_event = this.services.get('event');
svc_event.on('app.new-icon', async (_, data) => {
// for ( let i=0; i < 10; i++ ) {
// console.log('\x1B[36;1m--- app icon ---\x1B[0m');
// }
// console.log('INFO', {
// event: 'app.new-icon',
// uid: data.app_uid,
// });
// Writing icons as the system user
await svc_su.sudo(async () => {
for ( const size of ICON_SIZES ) {
const filename = `${data.app_uid}-${size}.png`;
console.log('FILENAME', filename);
const data_url = data.data_url;
const base64 = data_url.split(',')[1];
const input = Buffer.from(base64, 'base64');
// NOTE: A stream would be more ideal than a buffer here
// but we have no way of knowing the output size
// before we finish processing the image.
const output = await this.modules.sharp(input)
.resize(size)
.png()
.toBuffer();
const hl_write = new HLWrite();
await hl_write.run({
destination_or_parent: dir_app_icons,
specified_name: filename,
overwrite: true,
user: await svc_su.get_system_actor(),
no_thumbnail: true,
file: {
size: output.length,
name: filename,
mimetype: 'image/png',
type: 'image/png',
stream: buffer_to_stream(output),
},
});
}
})
});
}
async _init () {
}
}
module.exports = {
AppIconService,
};
+28 -1
View File
@@ -1,5 +1,5 @@
const { LLMkdir } = require("../filesystem/ll_operations/ll_mkdir");
const { RootNodeSelector } = require("../filesystem/node/selectors");
const { RootNodeSelector, NodeChildSelector } = require("../filesystem/node/selectors");
const { invalidate_cached_user } = require("../helpers");
const BaseService = require("./BaseService");
const { DB_WRITE } = require("./database/consts");
@@ -11,6 +11,33 @@ class UserService extends BaseService {
async _init () {
this.db = this.services.get('database').get(DB_WRITE, 'user-service');
this.dir_system = null;
}
async ['__on_boot.consolidation'] () {
const svc_fs = this.services.get('filesystem');
// Ensure system user has a home directory
const dir_system = await svc_fs.node(
new NodeChildSelector(
new RootNodeSelector(),
'system'
)
);
if ( ! await dir_system.exists() ) {
const svc_getUser = this.services.get('get-user');
await this.generate_default_fsentries({
user: await svc_getUser.get_user({ username: 'system' })
});
}
this.dir_system = dir_system;
this.services.emit('user.system-user-ready');
}
get_system_dir () {
return this.dir_system;
}
// used to be called: generate_system_fsentries