diff --git a/README.md b/README.md index b398d962b..66bc609d7 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [Publii](https://getpublii.com/) is a desktop-based CMS for Windows, Mac and Linux that makes creating static websites fast and hassle-free, even for beginners. -**Current version: 0.33.3 (build 11538)** +**Current version: 0.33.4 (build 11590)** ## Why Publii? Unlike static-site generators that are often unwieldy and difficult to use, Publii provides an diff --git a/app/back-end/app.js b/app/back-end/app.js index 3f30caa68..3bc30bd87 100644 --- a/app/back-end/app.js +++ b/app/back-end/app.js @@ -54,6 +54,7 @@ class App { this.sites = {}; this.sitesDir = null; this.app.sitesDir = null; + this.db = false; /* * Run the app @@ -193,6 +194,10 @@ class App { }; } + if (this.db) { + this.db.close(); + } + this.db = new sqlite(dbPath); let tags = new Tags(this, {site}); let posts = new Posts(this, {site}); diff --git a/app/back-end/builddata.json b/app/back-end/builddata.json index 467ea7fc7..e2ac6e48a 100644 --- a/app/back-end/builddata.json +++ b/app/back-end/builddata.json @@ -1 +1 @@ -{"version":"0.33.3","build":11544,"status":"Beta"} \ No newline at end of file +{"version":"0.33.4","build":11590,"status":"Beta"} \ No newline at end of file diff --git a/app/back-end/events/app.js b/app/back-end/events/app.js index b4cb55b91..ff7d8f04e 100644 --- a/app/back-end/events/app.js +++ b/app/back-end/events/app.js @@ -34,25 +34,32 @@ class AppEvents { if(appInstance.appConfig.sitesLocation) { let appFilesHelper = new AppFiles(appInstance); - result = appFilesHelper.relocateSites( - appInstance.appConfig.sitesLocation, - config.sitesLocation, - event - ); - } + + if (appInstance.db) { + appInstance.db.close(); + } - if(result) { - fs.writeFileSync(appInstance.appConfigPath, JSON.stringify(config)); - appInstance.appConfig = config; - } + setTimeout(() => { + result = appFilesHelper.relocateSites( + appInstance.appConfig.sitesLocation, + config.sitesLocation, + event + ); - appInstance.loadSites().then(() => { - event.sender.send('app-config-saved', { - status: true, - message: 'success-save', - sites: appInstance.sites - }); - }); + if(result) { + fs.writeFileSync(appInstance.appConfigPath, JSON.stringify(config)); + appInstance.appConfig = config; + } + + appInstance.loadSites().then(() => { + event.sender.send('app-config-saved', { + status: true, + message: 'success-save', + sites: appInstance.sites + }); + }); + }, 500); + } return; } diff --git a/app/back-end/events/deploy.js b/app/back-end/events/deploy.js index d3ff49fb0..18cfcdccc 100644 --- a/app/back-end/events/deploy.js +++ b/app/back-end/events/deploy.js @@ -35,16 +35,26 @@ class DeployEvents { self.deploymentProcess.send({ type: 'abort' }); - } catch(e) { + setTimeout(() => { + if (this.deploymentProcess) { + this.deploymentProcess.kill(); + } + }, 2000); + } catch(e) { + } } event.sender.send('app-deploy-aborted', true); }); - ipcMain.on('app-deploy-test', function(event, data) { - self.testConnection(data.deploymentConfig, data.siteName); + ipcMain.on('app-deploy-test', async (event, data) => { + try { + await this.testConnection(data.deploymentConfig, data.siteName); + } catch (err) { + console.log('Test connection error:', err); + } }); } diff --git a/app/back-end/events/site.js b/app/back-end/events/site.js index 56b647251..07c8bc066 100644 --- a/app/back-end/events/site.js +++ b/app/back-end/events/site.js @@ -323,6 +323,11 @@ class SiteEvents { // Load newly created db let siteDir = path.join(appInstance.sitesDir, config.name); let dbPath = path.join(siteDir, 'input', 'db.sqlite'); + + if (appInstance.db) { + appInstance.db.close(); + } + appInstance.db = new sqlite(dbPath); if(result !== false) { diff --git a/app/back-end/image.js b/app/back-end/image.js index ddd3d7e47..4af8d3448 100644 --- a/app/back-end/image.js +++ b/app/back-end/image.js @@ -272,11 +272,20 @@ class Image extends Model { } console.log('JIMP COVER', finalWidth, ' x ', finalHeight); - image.cover(finalWidth, finalHeight) - .quality(imagesQuality) - .write(destinationPath, function() { - resolve(destinationPath); - }); + + if (finalWidth === Jimp.AUTO || finalHeight === Jimp.AUTO) { + image.resize(finalWidth, finalHeight) + .quality(imagesQuality) + .write(destinationPath, function() { + resolve(destinationPath); + }); + } else { + image.cover(finalWidth, finalHeight) + .quality(imagesQuality) + .write(destinationPath, function() { + resolve(destinationPath); + }); + } }).catch(err => { console.log(err); reject(err); @@ -286,7 +295,7 @@ class Image extends Model { result = new Promise ((resolve, reject) => { if (extension.toLowerCase() === '.png') { sharp(originalPath) - .resize(finalWidth, finalHeight, { withoutEnlargement: true }) + .resize(finalWidth, finalHeight, { withoutEnlargement: true, fastShrinkOnLoad: false }) .toBuffer() .then(function (outputBuffer) { let wstream = fs.createWriteStream(destinationPath); @@ -297,7 +306,7 @@ class Image extends Model { }).catch(err => reject(err)) } else { sharp(originalPath) - .resize(finalWidth, finalHeight, { withoutEnlargement: true }) + .resize(finalWidth, finalHeight, { withoutEnlargement: true, fastShrinkOnLoad: false }) .jpeg({ quality: imagesQuality }) @@ -335,7 +344,7 @@ class Image extends Model { result = new Promise ((resolve, reject) => { if (extension.toLowerCase() === '.png') { sharp(originalPath) - .resize(finalWidth, finalHeight, { fit: 'inside', withoutEnlargement: true }) + .resize(finalWidth, finalHeight, { fit: 'inside', withoutEnlargement: true, fastShrinkOnLoad: false }) .toBuffer() .then(function (outputBuffer) { let wstream = fs.createWriteStream(destinationPath); @@ -345,7 +354,7 @@ class Image extends Model { }).catch(err => reject(err)); } else { sharp(originalPath) - .resize(finalWidth, finalHeight, { fit: 'inside', withoutEnlargement: true }) + .resize(finalWidth, finalHeight, { fit: 'inside', withoutEnlargement: true, fastShrinkOnLoad: false }) .jpeg({ quality: imagesQuality }) diff --git a/app/back-end/migrators/site-config.js b/app/back-end/migrators/site-config.js index 5e0aa37eb..d7763cc4c 100644 --- a/app/back-end/migrators/site-config.js +++ b/app/back-end/migrators/site-config.js @@ -48,6 +48,9 @@ class SiteConfigMigrator { delete siteConfig.author; fs.writeFileSync(configFilePath, JSON.stringify(siteConfig), {'flags': 'w'}); + // close DB connection + db.close(); + // Return modified (or not) site config return siteConfig; } diff --git a/app/back-end/modules/import/import.js b/app/back-end/modules/import/import.js index 4c1ce1ead..7206d7aba 100644 --- a/app/back-end/modules/import/import.js +++ b/app/back-end/modules/import/import.js @@ -34,6 +34,11 @@ class Import { } const dbPath = path.join(this.appInstance.sitesDir, this.siteName, 'input', 'db.sqlite'); + + if (this.appInstance.db) { + this.appInstance.db.close(); + } + this.appInstance.db = new sqlite(dbPath); } diff --git a/app/back-end/modules/import/wxr-parser.js b/app/back-end/modules/import/wxr-parser.js index c6c5498da..2c662d685 100644 --- a/app/back-end/modules/import/wxr-parser.js +++ b/app/back-end/modules/import/wxr-parser.js @@ -85,6 +85,7 @@ class WxrParser { results = xmlParser.toJson(this.fileContent); results = JSON.parse(results); } catch(e) { + console.log('An error occurred:', e); return false; } diff --git a/app/back-end/modules/render-html/contexts/post-preview.js b/app/back-end/modules/render-html/contexts/post-preview.js index 3dd5a3558..e203a7c38 100644 --- a/app/back-end/modules/render-html/contexts/post-preview.js +++ b/app/back-end/modules/render-html/contexts/post-preview.js @@ -82,17 +82,7 @@ class RendererContextPostPreview extends RendererContext { }; }); - this.tags.sort((tagA, tagB) => { - if(tagA.name < tagB.name) { - return -1; - } - - if(tagA.name > tagB.name) { - return 1; - } - - return 0; - }); + this.tags.sort((tagA, tagB) => tagA.name.localeCompare(tagB.name)); } this.metaTitle = 'It is an example value for the preview mode'; diff --git a/app/back-end/modules/render-html/contexts/post.js b/app/back-end/modules/render-html/contexts/post.js index 62fe65d6f..4529cb3de 100644 --- a/app/back-end/modules/render-html/contexts/post.js +++ b/app/back-end/modules/render-html/contexts/post.js @@ -6,7 +6,6 @@ const sqlString = require('sqlstring'); * Class used create context * for the single post theme views */ - class RendererContextPost extends RendererContext { loadData() { // Retrieve meta data diff --git a/app/back-end/modules/render-html/items/post.js b/app/back-end/modules/render-html/items/post.js index b6b3b7aba..5c2def12f 100644 --- a/app/back-end/modules/render-html/items/post.js +++ b/app/back-end/modules/render-html/items/post.js @@ -37,10 +37,10 @@ class PostItem { } } - if(this.siteConfig.advanced.urls.cleanUrls) { + if (this.siteConfig.advanced.urls.cleanUrls) { postURL = this.siteConfig.domain + '/' + this.post.slug + '/'; - if(this.renderer.previewMode || this.renderer.siteConfig.advanced.urls.addIndex) { + if (this.renderer.previewMode || this.renderer.siteConfig.advanced.urls.addIndex) { postURL += 'index.html'; } } @@ -65,23 +65,13 @@ class PostItem { this.postData.featuredImage = {}; - if(this.renderer.cachedItems.featuredImages[this.postData.id]) { + if (this.renderer.cachedItems.featuredImages[this.postData.id]) { this.postData.featuredImage = this.renderer.cachedItems.featuredImages[this.postData.id]; } - if(this.renderer.cachedItems.postTags[this.postID]) { + if (this.renderer.cachedItems.postTags[this.postID]) { this.postData.tags = this.renderer.cachedItems.postTags[this.postID].map(tagID => this.renderer.cachedItems.tags[tagID]); - this.postData.tags.sort((tagA, tagB) => { - if(tagA.name.toLowerCase() < tagB.name.toLowerCase()) { - return -1; - } - - if(tagA.name.toLowerCase() > tagB.name.toLowerCase()) { - return 1; - } - - return 0; - }); + this.postData.tags.sort((tagA, tagB) => tagA.name.localeCompare(tagB.name)); } else { this.postData.tags = []; } diff --git a/app/back-end/modules/render-html/renderer-context.js b/app/back-end/modules/render-html/renderer-context.js index 00354cbc6..20a0abf16 100644 --- a/app/back-end/modules/render-html/renderer-context.js +++ b/app/back-end/modules/render-html/renderer-context.js @@ -155,6 +155,8 @@ class RendererContext { tags = tags.filter(tag => tag.postsNumber > 0); } + tags.sort((tagA, tagB) => tagA.name.localeCompare(tagB.name)); + return tags; } @@ -170,6 +172,8 @@ class RendererContext { authors = authors.filter(author => author.postsNumber > 0); } + authors.sort((authorA, authorB) => authorA.name.localeCompare(authorB.name)); + return authors; } @@ -236,7 +240,10 @@ class RendererContext { bodyCustomCode: this.siteConfig.advanced.customBodyCode || '', footerCustomCode: this.siteConfig.advanced.customFooterCode || '', footerAmpCustomCode: this.siteConfig.advanced.customFooterAmpCode || '', - customHTML: this.siteConfig.advanced.customHTML || false + customHTML: this.siteConfig.advanced.customHTML || false, + utils: { + currentYear: new Date().getFullYear() + } }; // In AMP mode create special global @amp variable diff --git a/app/back-end/modules/render-html/renderer.js b/app/back-end/modules/render-html/renderer.js index d49397414..ff4c556e6 100644 --- a/app/back-end/modules/render-html/renderer.js +++ b/app/back-end/modules/render-html/renderer.js @@ -154,6 +154,7 @@ class Renderer { this.generateAMP(); console.timeEnd("RENDERING"); this.sendProgress(100, 'Website files are ready to upload'); + this.db.close(); } /** diff --git a/app/back-end/site.js b/app/back-end/site.js index ca938cfa7..86c5d7b09 100644 --- a/app/back-end/site.js +++ b/app/back-end/site.js @@ -94,6 +94,7 @@ class Site { let dbPath = path.join(this.siteDir, 'input', 'db.sqlite'); let db = new sqlite(dbPath); db.exec(fs.readFileSync(this.application.basedir + '/back-end/sql/1.0.0.sql', 'utf8')); + db.close(); } /* @@ -107,6 +108,7 @@ class Site { name: authorName, slug: slug(authorName).toLowerCase() }); + db.close(); } /* @@ -251,6 +253,8 @@ class Site { sender.send('app-site-regenerate-thumbnails-success', true); } }); + + db.close(); } /** @@ -309,7 +313,14 @@ class Site { */ static delete(appInstance, name) { let sitePath = path.join(appInstance.sitesDir, name); - fs.removeSync(sitePath); + + if (appInstance.db) { + appInstance.db.close(); + } + + setTimeout(() => { + fs.removeSync(sitePath); + }, 500); } /* diff --git a/app/package-lock.json b/app/package-lock.json index 1e7d2e7e0..6b1efc212 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -1,6 +1,6 @@ { "name": "Publii", - "version": "0.33.3", + "version": "0.33.4", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/app/package.json b/app/package.json index b2406429f..08fd475ce 100644 --- a/app/package.json +++ b/app/package.json @@ -1,7 +1,7 @@ { "productName": "Publii", "name": "Publii", - "version": "0.33.3", + "version": "0.33.4", "description": "Static Site CMS", "main": "main.js", "scripts": { diff --git a/app/src/assets/svg/svg-map.svg b/app/src/assets/svg/svg-map.svg index 25abc43d2..47ef01c85 100755 --- a/app/src/assets/svg/svg-map.svg +++ b/app/src/assets/svg/svg-map.svg @@ -660,6 +660,258 @@ c0.9,0,1.7-0.5,2-1.2l2.8-6.4C23.4,11.3,22.3,10,20.8,10z M2,6.1C2,5.4,2.4,5,2.7,5h5.2l2.2,2.7L10.4,8h6.9C17.6,8,18,8.4,18,9.1V10 H6c-0.9,0-1.7,0.5-2,1.2l-2,4.5V6.1z"/> - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/components/App.vue b/app/src/components/App.vue index d04280dcd..e36b015a4 100644 --- a/app/src/components/App.vue +++ b/app/src/components/App.vue @@ -308,4 +308,16 @@ body[data-os="linux"] { } } } + +/* + * Responsive improvements + */ + +@media (max-width: 1400px) { + .app { + &-site-sidebar { + width: 32rem; + } + } +} diff --git a/app/src/components/Posts.vue b/app/src/components/Posts.vue index d06f8eeb2..1b550b08e 100644 --- a/app/src/components/Posts.vue +++ b/app/src/components/Posts.vue @@ -335,17 +335,7 @@ export default { items.forEach((item, i) => { if (item.tags.length) { - item.tags.sort((tagA, tagB) => { - if(tagA.name.toLowerCase() < tagB.name.toLowerCase()) { - return -1; - } - - if(tagA.name.toLowerCase() > tagB.name.toLowerCase()) { - return 1; - } - - return 0; - }); + item.tags.sort((tagA, tagB) => tagA.name.localeCompare(tagB.name)); } }); diff --git a/app/src/components/RegenerateThumbnails.vue b/app/src/components/RegenerateThumbnails.vue index 4d6d1c157..ddb47480a 100644 --- a/app/src/components/RegenerateThumbnails.vue +++ b/app/src/components/RegenerateThumbnails.vue @@ -30,7 +30,7 @@

List of the regenerated files:

@@ -63,7 +63,8 @@ export default { ], data: function() { return { - regeneratingThumbnails: false, + regeneratingInProgress: false, + regeneratingStarted: false, resultLabel: '', resultCssClass: { 'error': false, @@ -83,12 +84,13 @@ export default { return filePath.replace(this.$store.state.currentSite.siteDir, ''); }, regenerate: function() { - if(this.regeneratingThumbnails) { + if(this.regeneratingInProgress) { return; } this.buttonStatus = 'disabled preloader'; - this.regeneratingThumbnails = true; + this.regeneratingInProgress = true; + this.regeneratingStarted = true; this.files = []; this.resultLabel = 'Regenerating thumbnails...'; this.resultCssClass = { @@ -97,6 +99,10 @@ export default { 'success': false }; + ipcRenderer.removeAllListeners('app-site-regenerate-thumbnails-error'); + ipcRenderer.removeAllListeners('app-site-regenerate-thumbnails-progress'); + ipcRenderer.removeAllListeners('app-site-regenerate-thumbnails-success'); + setTimeout(() => { ipcRenderer.send('app-site-regenerate-thumbnails', { name: this.$store.state.currentSite.config.name @@ -130,6 +136,7 @@ export default { }; this.resultLabel = 'All thumbnails have been created.'; this.buttonStatus = ''; + this.regeneratingInProgress = false; }); }, 350); } diff --git a/app/src/components/ServerSettings.vue b/app/src/components/ServerSettings.vue index 5bec4d6e9..2a30fad47 100644 --- a/app/src/components/ServerSettings.vue +++ b/app/src/components/ServerSettings.vue @@ -21,17 +21,69 @@ + + +
- INTRO + class="server-settings-intro"> + +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
-
- Select Github Pages +
+ +
+ +
+
-
- Select S3 +
+ +
+ +
+
@@ -83,35 +135,35 @@ class="note" slot="note" v-if="deploymentMethodSelected === 'netlify'"> - Read how to configure Netlify website. + Read how to configure a website using Netlify. - Read how to configure a Github Pages website. + Read how to configure a website using Github Pages - Read how to configure a GitLab Pages website. + Read how to configure a website using GitLab Pages - Read how to configure a S3 website. + Read how to configure a website using S3 - Read how to configure a Google Cloud website. + Read how to configure a website using Google Cloud @@ -124,6 +176,9 @@ id="port" type="number" key="port" + min="1" + max="65535" + step="1" :class="{ 'is-invalid': errors.indexOf('port') > -1 }" @keyup.native="cleanError('port')" v-model="deploymentSettings.port" /> @@ -131,7 +186,7 @@ slot="note" v-if="errors.indexOf('port') > -1" class="note"> - The port field cannot be empty. + The port field cannot be empty and must be a positive integer between 1 and 65535. @@ -768,10 +823,10 @@ export default { currentHttpProtocol () { if (this.$store.state.currentSite.config.domain.indexOf('file') === 0) { return 'file'; - } else if (this.$store.state.currentSite.config.domain.indexOf('http') === 0) { - return 'http'; - } else { + } else if (this.$store.state.currentSite.config.domain.indexOf('https') === 0) { return 'https'; + } else { + return 'http'; } }, siteIsOnline () { @@ -937,8 +992,6 @@ export default { return; } - this.save(); - let deploymentSettings = this.getDeploymentSettings().deployment; if(password) { @@ -959,6 +1012,7 @@ export default { }); this.testInProgress = false; + this.save(); }); ipcRenderer.once('app-deploy-test-write-error', (event, data) => { @@ -1019,7 +1073,9 @@ export default { return !this.errors.length; }, validateFtp () { - if (this.deploymentSettings.port.trim() === '') { + let portValue = parseInt(this.deploymentSettings.port.trim(), 10) + + if (this.deploymentSettings.port.trim() === '' || isNaN(portValue) || portValue < 1 || portValue > 65535) { this.errors.push('port'); } @@ -1119,5 +1175,37 @@ export default { .is-invalid + .note { color: $color-3; } + + &-intro { + display: grid; + grid-template-columns: repeat(3, 1fr); + grid-gap: 2rem; + + & > div { + align-items: center; + background: $color-9; + border: 2px solid transparent; + display: flex; + justify-content: center; + min-height: calc(8rem + 8vh); + transition: all .25s ease-out; + + &:hover { + background: $color-10; + border-color: $color-0; + box-shadow: 0 0 26px rgba(black, .07); + cursor: pointer; + + & > svg { + fill: $color-1; + } + } + + & > svg { + fill: $color-5; + transition: inherit; + } + } + } } diff --git a/app/src/components/Settings.vue b/app/src/components/Settings.vue index 4ebc6aae1..4e6a37791 100644 --- a/app/src/components/Settings.vue +++ b/app/src/components/Settings.vue @@ -49,6 +49,18 @@ :items="availableLanguages"> + + + + @@ -1303,6 +1315,7 @@ export default { icon: '' }, language: '', + customLanguage: '', name: '', theme: '', currentTheme: '', @@ -1396,6 +1409,12 @@ export default { this.logo.color = this.$store.state.currentSite.config.logo.color; this.logo.icon = this.$store.state.currentSite.config.logo.icon; this.language = this.$store.state.currentSite.config.language; + + if (!this.availableLanguages[this.language]) { + this.customLanguage = this.language; + this.language = 'custom'; + } + this.name = this.$store.state.currentSite.config.displayName; this.setCurrentTheme(); this.advanced = Object.assign({}, this.advanced, this.$store.state.currentSite.config.advanced); @@ -1433,7 +1452,12 @@ export default { icon: this.$refs['logo-creator'].getActiveIcon(), color: this.$refs['logo-creator'].getActiveColor() }; - newSettings.language = this.language; + + if (this.language === 'custom') { + newSettings.language = this.customLanguage; + } else { + newSettings.language = this.language; + } // Remove GDPR script groups with empty name or ID this.advanced.gdpr.groups = this.advanced.gdpr.groups.filter(group => { if (group.name === '') { diff --git a/app/src/components/Site.vue b/app/src/components/Site.vue index c31a8199f..120bbd9ab 100644 --- a/app/src/components/Site.vue +++ b/app/src/components/Site.vue @@ -187,8 +187,12 @@ export default { @media (max-width: 1400px) { .site { + .sidebar { + width: 32rem; + } .content { padding: 4rem; + width: calc(100% - 32rem); } } } diff --git a/app/src/components/SyncPopup.vue b/app/src/components/SyncPopup.vue index 588c370ba..030c3285c 100644 --- a/app/src/components/SyncPopup.vue +++ b/app/src/components/SyncPopup.vue @@ -413,6 +413,7 @@ export default { }); ipcRenderer.once('app-deploy-aborted', (event) => { + this.$store.commit('setSidebarStatus', 'not-synced'); this.close(); }); }, diff --git a/app/src/components/TopBarNotification.vue b/app/src/components/TopBarNotification.vue index 38b6c6731..cd8e2fc10 100644 --- a/app/src/components/TopBarNotification.vue +++ b/app/src/components/TopBarNotification.vue @@ -4,7 +4,7 @@ v-if="notification.visible" :data-timestamp="notification.timestamp" > @@ -22,6 +22,11 @@ import { ipcRenderer, shell } from 'electron'; export default { name: 'topbar-notification', + data () { + return { + contentEventsAdded: false + } + }, computed: { notification: function() { return this.$store.state.app.notification; @@ -32,20 +37,6 @@ export default { }, mounted: function() { let self = this; - - setTimeout(() => { - if(!this.$refs.text) { - return; - } - - this.$refs.text.addEventListener('click', function(e) { - if(e.target.tagName === 'A') { - e.preventDefault(); - shell.openExternal(e.target.getAttribute('href')); - self.closeNotification(); - } - }); - }, 0); }, methods: { getNotifications() { @@ -95,6 +86,26 @@ export default { visible: false }); } + + setTimeout(() => { + if(!this.$refs.content) { + return; + } + + if (this.contentEventsAdded) { + return; + } + + this.$refs.content.addEventListener('click', e => { + if(e.target.tagName === 'A') { + e.preventDefault(); + shell.openExternal(e.target.getAttribute('href')); + this.closeNotification(); + } + }); + + this.contentEventsAdded = true; + }, 500); }, closeNotification(event) { localStorage.setItem('publii-notification-close-timestamp', this.notification.timestamp); diff --git a/app/src/components/basic-elements/TextInput.vue b/app/src/components/basic-elements/TextInput.vue index 50b774c16..d5bf06638 100644 --- a/app/src/components/basic-elements/TextInput.vue +++ b/app/src/components/basic-elements/TextInput.vue @@ -195,7 +195,7 @@ export default { &.is-number { display: inline-block; - width: 8rem; + width: 12rem; } svg { diff --git a/app/src/components/configs/postEditor.config.js b/app/src/components/configs/postEditor.config.js index 433b4da33..0a0e8307e 100644 --- a/app/src/components/configs/postEditor.config.js +++ b/app/src/components/configs/postEditor.config.js @@ -3,7 +3,7 @@ export default { file_picker_types: 'image', plugins: "advlist autolink autosave link image lists hr pagebreak searchreplace media table paste autoresize autosave textpattern toc", toolbar1: "bold italic underline strikethrough link unlink blockquote alignleft aligncenter alignright bullist numlist image gallery media table toc", - toolbar2: "styleselect formatselect searchreplace hr readmore removeformat undo redo restoredraft sourcecode ", + toolbar2: "styleselect formatselect searchreplace hr readmore undo redo restoredraft removeformat sourcecode", toolbar3: "", block_formats: 'Paragraph=p;Heading 2=h2;Heading 3=h3;Heading 4=h4;Heading 5=h5;Heading 6=h6;Address=address;Pre=pre;Code=code;Blockquote=blockquote', extended_valid_elements: "a[*],altGlyph[*],altGlyphDef[*],altGlyphItem[*],animate[*],animateColor[*],animateMotion[*],animateTransform[*],circle[*],clipPath[*],color-profile[*],cursor[*],defs[*],desc[*],discard[*],ellipse[*],feBlend[*],feColorMatrix[*],feComponentTransfer[*],feComposite[*],feConvolveMatrix[*],feDiffuseLighting[*],feDisplacementMap[*],feDistantLight[*],feDropShadow[*],feFlood[*],feFuncA[*],feFuncB[*],feFuncG[*],feFuncR[*],feGaussianBlur[*],feImage[*],feMerge[*],feMergeNode[*],feMorphology[*],feOffset[*],fePointLight[*],feSpecularLighting[*],feSpotLight[*],feTile[*],feTurbulence[*],filter[*],font[*],font-face[*],font-face-format[*],font-face-name[*],font-face-src[*],font-face-uri[*],foreignObject[*],g[*],glyph[*],glyphRef[*],hatch[*],hatchpath[*],hkern[*],iframe[*],image[*],line[*],linearGradient[*],marker[*],mask[*],mesh[*],meshgradient[*],meshpatch[*],meshrow[*],metadata[*],missing-glyph[*],mpath[*],path[*],pattern[*],polygon[*],polyline[*],radialGradient[*],rect[*],set[*],solidcolor[*],stop[*],style[*],svg[*],switch[*],symbol[*],text[*],textPath[*],title[*],tref[*],tspan[*],unknown[*],use[*],view[*],vkern[*],publii-amp,publii-non-amp,script[*],i[*],video[*],audio[*],source[*],stream[*]", diff --git a/app/src/components/post-editor/Sidebar.vue b/app/src/components/post-editor/Sidebar.vue index a7547d3e6..9e43418dc 100644 --- a/app/src/components/post-editor/Sidebar.vue +++ b/app/src/components/post-editor/Sidebar.vue @@ -279,7 +279,15 @@ size="m" name="sidebar-seo"/> - SEO + + SEO + + + Post slug is too long + + + + The post slug longer than 250 characters can lead to creation of broken files during the website rendering. +