mirror of
https://github.com/HeyPuter/puter.git
synced 2025-01-23 14:20:22 +08:00
dev: add icon_size query for get-launch-apps
This commit is contained in:
parent
f14e1fefcf
commit
df10a7c332
@ -22,6 +22,41 @@ const router = express.Router();
|
||||
const auth = require('../middleware/auth.js');
|
||||
const { get_app } = require('../helpers.js');
|
||||
const { DB_READ } = require('../services/database/consts.js');
|
||||
const { stream_to_buffer } = require('../util/streamutil.js');
|
||||
|
||||
const get_apps = async ({ specifiers }) => {
|
||||
return await Promise.all(specifiers.map(async (specifier) => {
|
||||
return await get_app(specifier);
|
||||
}));
|
||||
};
|
||||
|
||||
const iconify_apps = async (context, { apps, size }) => {
|
||||
return await Promise.all(apps.map(async app => {
|
||||
const data_url = app.icon;
|
||||
if ( ! data_url ) return app;
|
||||
|
||||
const metadata = data_url.split(',')[0];
|
||||
const input_mime = metadata.split(';')[0].split(':')[1];
|
||||
|
||||
// svg icons will be sent as-is
|
||||
if (input_mime === 'image/svg+xml') {
|
||||
return app;
|
||||
}
|
||||
|
||||
const svc_appIcon = context.services.get('app-icon');
|
||||
const { stream, mime } = await svc_appIcon.get_icon_stream({
|
||||
app_icon: app.icon,
|
||||
app_uid: app.uid ?? app.uuid,
|
||||
size: size,
|
||||
});
|
||||
|
||||
const buffer = await stream_to_buffer(stream);
|
||||
const resp_data_url = `data:image/png;base64,${buffer.toString('base64')}`;
|
||||
|
||||
app.icon = resp_data_url;
|
||||
return app;
|
||||
}));
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------//
|
||||
// GET /get-launch-apps
|
||||
@ -29,10 +64,22 @@ const { DB_READ } = require('../services/database/consts.js');
|
||||
module.exports = async (req, res) => {
|
||||
let result = {};
|
||||
|
||||
// Verify query params
|
||||
if ( req.query.icon_size ) {
|
||||
const ALLOWED_SIZES = ['16', '32', '64', '128', '256', '512'];
|
||||
|
||||
if ( ! ALLOWED_SIZES.includes(req.query.icon_size) ) {
|
||||
res.status(400).send({ error: 'Invalid icon_size' });
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------//
|
||||
// Recommended apps
|
||||
// -----------------------------------------------------------------------//
|
||||
result.recommended = kv.get('global:recommended-apps');
|
||||
const recommended_cache_key = 'global:recommended-apps' + (
|
||||
req.query.icon_size ? `:icon-size:${req.query.icon_size}` : ''
|
||||
);
|
||||
result.recommended = kv.get(recommended_cache_key);
|
||||
if ( ! result.recommended ) {
|
||||
let app_names = new Set([
|
||||
'app-center',
|
||||
@ -62,12 +109,10 @@ module.exports = async (req, res) => {
|
||||
|
||||
// Prepare each app for returning to user by only returning the necessary fields
|
||||
// and adding them to the retobj array
|
||||
result.recommended = [];
|
||||
for ( const name of app_names ) {
|
||||
const app = await get_app({ name });
|
||||
if ( ! app ) continue;
|
||||
|
||||
result.recommended.push({
|
||||
result.recommended = (await get_apps({
|
||||
specifiers: Array.from(app_names).map(name => ({ name }))
|
||||
})).filter(app => !! app).map(app => {
|
||||
return {
|
||||
uuid: app.uid,
|
||||
name: app.name,
|
||||
title: app.title,
|
||||
@ -75,10 +120,18 @@ module.exports = async (req, res) => {
|
||||
godmode: app.godmode,
|
||||
maximize_on_start: app.maximize_on_start,
|
||||
index_url: app.index_url,
|
||||
};
|
||||
});
|
||||
|
||||
// Iconify apps
|
||||
if ( req.query.icon_size ) {
|
||||
result.recommended = await iconify_apps({ services: req.services }, {
|
||||
apps: result.recommended,
|
||||
size: req.query.icon_size,
|
||||
});
|
||||
}
|
||||
|
||||
kv.set('global:recommended-apps', result.recommended);
|
||||
kv.set(recommended_cache_key, result.recommended);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------//
|
||||
@ -122,5 +175,13 @@ module.exports = async (req, res) => {
|
||||
});
|
||||
}
|
||||
|
||||
// Iconify apps
|
||||
if ( req.query.icon_size ) {
|
||||
result.recent = await iconify_apps({ services: req.services }, {
|
||||
apps: result.recent,
|
||||
size: req.query.icon_size,
|
||||
});
|
||||
}
|
||||
|
||||
return res.send(result);
|
||||
};
|
||||
|
@ -124,6 +124,7 @@ describe('GET /launch-apps', () => {
|
||||
// First call
|
||||
{
|
||||
const { get_launch_apps, req_mock, res_mock, spies } = get_mock_context();
|
||||
req_mock.query = {};
|
||||
await get_launch_apps(req_mock, res_mock);
|
||||
|
||||
expect(res_mock.send.calledOnce).to.equal(true, 'res.send should be called once');
|
||||
@ -177,6 +178,7 @@ describe('GET /launch-apps', () => {
|
||||
// Second call
|
||||
{
|
||||
const { get_launch_apps, req_mock, res_mock, spies } = get_mock_context();
|
||||
req_mock.query = {};
|
||||
await get_launch_apps(req_mock, res_mock);
|
||||
|
||||
expect(res_mock.send.calledOnce).to.equal(true, 'res.send should be called once');
|
||||
|
@ -62,20 +62,21 @@ class AppIconService extends BaseService {
|
||||
}).attach(app);
|
||||
}
|
||||
|
||||
async get_icon_stream ({ app_uid, size }) {
|
||||
async get_icon_stream ({ app_icon, app_uid, size }) {
|
||||
// Get icon file node
|
||||
const dir_app_icons = await this.get_app_icons();
|
||||
console.log('APP UID', app_uid);
|
||||
const node = await dir_app_icons.getChild(`${app_uid}-${size}.png`);
|
||||
if ( ! await node.exists() ) {
|
||||
// Use database-stored icon as a fallback
|
||||
const app = await get_app({ uid: app_uid });
|
||||
if ( ! app.icon ) {
|
||||
app.icon = DEFAULT_APP_ICON;
|
||||
}
|
||||
const [metadata, app_icon] = app.icon.split(',');
|
||||
app_icon = app_icon ?? await (async () => {
|
||||
const app = await get_app({ uid: app_uid });
|
||||
return app.icon ?? DEFAULT_APP_ICON;
|
||||
})()
|
||||
const [metadata, base64] = app_icon.split(',');
|
||||
console.log('METADATA', metadata);
|
||||
const mime = metadata.split(';')[0].split(':')[1];
|
||||
const img = Buffer.from(app_icon, 'base64');
|
||||
const img = Buffer.from(base64, 'base64');
|
||||
return {
|
||||
mime,
|
||||
stream: buffer_to_stream(img),
|
||||
|
Loading…
Reference in New Issue
Block a user