mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-27 09:06:15 +01:00
feat: upload maskable icon for PWA
This commit is contained in:
@@ -29,7 +29,8 @@
|
|||||||
"favicon.upload": "Upload",
|
"favicon.upload": "Upload",
|
||||||
"touch-icon": "Homescreen/Touch Icon",
|
"touch-icon": "Homescreen/Touch Icon",
|
||||||
"touch-icon.upload": "Upload",
|
"touch-icon.upload": "Upload",
|
||||||
"touch-icon.help": "Recommended size and format: 192x192, PNG format only. If no touch icon is specified, NodeBB will fall back to using the favicon.",
|
"touch-icon.help": "Recommended size and format: 512x512, PNG format only. If no touch icon is specified, NodeBB will fall back to using the favicon.",
|
||||||
|
"maskable-icon.help": "Recommended size and format: 512x512, PNG format only. If no maskable icon is specified, NodeBB will fall back to the Touch Icon",
|
||||||
"outgoing-links": "Outgoing Links",
|
"outgoing-links": "Outgoing Links",
|
||||||
"outgoing-links.warning-page": "Use Outgoing Links Warning Page",
|
"outgoing-links.warning-page": "Use Outgoing Links Warning Page",
|
||||||
"search-default-sort-by": "Search default sort by",
|
"search-default-sort-by": "Search default sort by",
|
||||||
@@ -38,4 +39,4 @@
|
|||||||
"theme-color": "Theme Color",
|
"theme-color": "Theme Color",
|
||||||
"background-color": "Background Color",
|
"background-color": "Background Color",
|
||||||
"background-color-help": "Color used for splash screen background when website is installed as a PWA"
|
"background-color-help": "Color used for splash screen background when website is installed as a PWA"
|
||||||
}
|
}
|
||||||
@@ -2606,7 +2606,40 @@ paths:
|
|||||||
description: The filename
|
description: The filename
|
||||||
url:
|
url:
|
||||||
type: string
|
type: string
|
||||||
description: URL of the uploaded image for use client-side
|
description: URL of the uploaded logo for the Homescreen/Touch Icon to enable PWA
|
||||||
|
/api/admin/uploadMaskableIcon:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- admin
|
||||||
|
summary: Upload Maskable Icon
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
multipart/form-data:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
files:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
format: binary
|
||||||
|
required:
|
||||||
|
- files
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: "Image uploaded"
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
description: The filename
|
||||||
|
url:
|
||||||
|
type: string
|
||||||
|
description: URL of the uploaded logo for the Maskable Icon entry for PWA / A2HS
|
||||||
/api/admin/uploadlogo:
|
/api/admin/uploadlogo:
|
||||||
post:
|
post:
|
||||||
tags:
|
tags:
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ define('admin/settings/general', ['admin/settings'], function () {
|
|||||||
$('button[data-action="removeTouchIcon"]').on('click', function () {
|
$('button[data-action="removeTouchIcon"]').on('click', function () {
|
||||||
$('input[data-field="brand:touchIcon"]').val('');
|
$('input[data-field="brand:touchIcon"]').val('');
|
||||||
});
|
});
|
||||||
|
$('button[data-action="removeMaskableIcon"]').on('click', function () {
|
||||||
|
$('input[data-field="brand:maskableIcon"]').val('');
|
||||||
|
});
|
||||||
$('button[data-action="removeOgImage"]').on('click', function () {
|
$('button[data-action="removeOgImage"]').on('click', function () {
|
||||||
$('input[data-field="removeOgImage"]').val('');
|
$('input[data-field="removeOgImage"]').val('');
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -166,6 +166,23 @@ uploadsController.uploadTouchIcon = async function (req, res, next) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
uploadsController.uploadMaskableIcon = async function (req, res, next) {
|
||||||
|
const uploadedFile = req.files.files[0];
|
||||||
|
const allowedTypes = ['image/png'];
|
||||||
|
|
||||||
|
if (validateUpload(res, uploadedFile, allowedTypes)) {
|
||||||
|
try {
|
||||||
|
const imageObj = await file.saveFileToLocal('maskableicon-orig.png', 'system', uploadedFile.path);
|
||||||
|
res.json([{ name: uploadedFile.name, url: imageObj.url }]);
|
||||||
|
} catch (err) {
|
||||||
|
next(err);
|
||||||
|
} finally {
|
||||||
|
file.delete(uploadedFile.path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
uploadsController.uploadLogo = async function (req, res, next) {
|
uploadsController.uploadLogo = async function (req, res, next) {
|
||||||
await upload('site-logo', req, res, next);
|
await upload('site-logo', req, res, next);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -294,6 +294,22 @@ Controllers.manifest = function (req, res, next) {
|
|||||||
density: 10.0,
|
density: 10.0,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (meta.config['brand:maskableIcon']) {
|
||||||
|
manifest.icons.push({
|
||||||
|
src: nconf.get('relative_path') + '/assets/uploads/system/maskableicon-orig.png',
|
||||||
|
type: 'image/png',
|
||||||
|
purpose: 'maskable',
|
||||||
|
});
|
||||||
|
} else if (meta.config['brand:touchIcon']) {
|
||||||
|
manifest.icons.push({
|
||||||
|
src: nconf.get('relative_path') + '/assets/uploads/system/touchicon-orig.png',
|
||||||
|
type: 'image/png',
|
||||||
|
purpose: 'maskable',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
plugins.fireHook('filter:manifest.build', { req: req, res: res, manifest: manifest }, function (err, data) {
|
plugins.fireHook('filter:manifest.build', { req: req, res: res, manifest: manifest }, function (err, data) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return next(err);
|
return next(err);
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ function apiRoutes(router, middleware, controllers) {
|
|||||||
router.post('/api/admin/category/uploadpicture', middlewares, helpers.tryRoute(controllers.admin.uploads.uploadCategoryPicture));
|
router.post('/api/admin/category/uploadpicture', middlewares, helpers.tryRoute(controllers.admin.uploads.uploadCategoryPicture));
|
||||||
router.post('/api/admin/uploadfavicon', middlewares, helpers.tryRoute(controllers.admin.uploads.uploadFavicon));
|
router.post('/api/admin/uploadfavicon', middlewares, helpers.tryRoute(controllers.admin.uploads.uploadFavicon));
|
||||||
router.post('/api/admin/uploadTouchIcon', middlewares, helpers.tryRoute(controllers.admin.uploads.uploadTouchIcon));
|
router.post('/api/admin/uploadTouchIcon', middlewares, helpers.tryRoute(controllers.admin.uploads.uploadTouchIcon));
|
||||||
|
router.post('/api/admin/uploadMaskableIcon', middlewares, helpers.tryRoute(controllers.admin.uploads.uploadMaskableIcon));
|
||||||
router.post('/api/admin/uploadlogo', middlewares, helpers.tryRoute(controllers.admin.uploads.uploadLogo));
|
router.post('/api/admin/uploadlogo', middlewares, helpers.tryRoute(controllers.admin.uploads.uploadLogo));
|
||||||
router.post('/api/admin/uploadOgImage', middlewares, helpers.tryRoute(controllers.admin.uploads.uploadOgImage));
|
router.post('/api/admin/uploadOgImage', middlewares, helpers.tryRoute(controllers.admin.uploads.uploadOgImage));
|
||||||
router.post('/api/admin/upload/file', middlewares, helpers.tryRoute(controllers.admin.uploads.uploadFile));
|
router.post('/api/admin/upload/file', middlewares, helpers.tryRoute(controllers.admin.uploads.uploadFile));
|
||||||
|
|||||||
@@ -117,6 +117,19 @@
|
|||||||
[[admin/settings/general:touch-icon.help]]
|
[[admin/settings/general:touch-icon.help]]
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="input-group">
|
||||||
|
<input id="maskableIconUrl" type="text" class="form-control" data-field="brand:maskableIcon" data-action="upload" data-target="maskableIconUrl" data-route="{config.relative_path}/api/admin/uploadMaskableIcon" readonly />
|
||||||
|
<span class="input-group-btn">
|
||||||
|
<input data-action="upload" data-target="maskableIconUrl" data-route="{config.relative_path}/api/admin/uploadMaskableIcon" type="button" class="btn btn-default" value="[[admin/settings/general:touch-icon.upload]]"></input>
|
||||||
|
<button data-action="removeMaskableIcon" type="button" class="btn btn-default btn-danger"><i class="fa fa-times"></i></button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<p class="help-block">
|
||||||
|
[[admin/settings/general:maskable-icon.help]]
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user