diff --git a/css/newTabPage.css b/css/newTabPage.css index 26937cede..2aa0bea58 100644 --- a/css/newTabPage.css +++ b/css/newTabPage.css @@ -17,6 +17,12 @@ body:not(.is-ntp) #ntp-content { height: 100%; margin: auto; object-fit: cover; + transition: 0.2s filter, 0.2s transform; + transform: scale(1.03); +} + +.ntp-blur #ntp-background { + filter: blur(12px); } #ntp-background-controls { diff --git a/css/searchbar.css b/css/searchbar.css index c019556c0..e9efeaec0 100644 --- a/css/searchbar.css +++ b/css/searchbar.css @@ -11,6 +11,15 @@ -webkit-user-select: none; max-height: calc(100% - 125px); overflow-y: auto; + transition: 0.2s opacity, 0.2s visibility; + opacity: 1; + visibility: visible; +} + +#searchbar.searchbar-hidden { + opacity: 0; + visibility: hidden; + pointer-events: none; } body:not(.is-ntp) #searchbar, diff --git a/js/browserUI.js b/js/browserUI.js index eab152329..0f79fb1c3 100644 --- a/js/browserUI.js +++ b/js/browserUI.js @@ -43,6 +43,19 @@ function addTab (tabId = tabs.add(), options = {}) { destroyTab(tabs.getSelected()) } + // if the tab is a new, blank tab, replace it with the custom new tab page + let isCustomUrl = false + if (!tabs.get(tabId).url && !tabs.get(tabId).private) { + const newTabUrl = settings.get('newTabUrl') + if (newTabUrl === 'customUrl') { + const customUrl = settings.get('newTabCustomUrl') + if (customUrl) { + tabs.update(tabId, { url: customUrl }) + isCustomUrl = true + } + } + } + tabBar.addTab(tabId) webviews.add(tabId) @@ -50,7 +63,8 @@ function addTab (tabId = tabs.add(), options = {}) { switchToTab(tabId, { focusWebview: options.enterEditMode === false }) - if (options.enterEditMode !== false) { + // Don't enter edit mode for custom URLs - just show the website + if (options.enterEditMode !== false && !isCustomUrl) { tabEditor.show(tabId) } } else { diff --git a/js/navbar/tabEditor.js b/js/navbar/tabEditor.js index 14cf3db20..56dc56e8b 100644 --- a/js/navbar/tabEditor.js +++ b/js/navbar/tabEditor.js @@ -5,6 +5,8 @@ var urlParser = require('util/urlParser.js') var keyboardNavigationHelper = require('util/keyboardNavigationHelper.js') var bookmarkStar = require('navbar/bookmarkStar.js') var contentBlockingToggle = require('navbar/contentBlockingToggle.js') +var newTabPage = require('newTabPage.js') +var settings = require('util/settings/settings.js') const tabEditor = { container: document.getElementById('tab-editor'), @@ -45,8 +47,18 @@ const tabEditor = { if (showSearchbar !== false) { if (editingValue) { searchbar.showResults(editingValue, null) + searchbar.el.classList.remove('searchbar-hidden') } else { searchbar.showResults('', null) + const newTabUrlMode = settings.get('newTabUrl') + const isNTP = (newTabUrlMode === 'backgroundImage' && currentURL === '') || + (newTabUrlMode === 'customUrl' && currentURL === settings.get('newTabCustomUrl')) + + if (isNTP) { + searchbar.el.classList.add('searchbar-hidden') + } else { + searchbar.el.classList.remove('searchbar-hidden') + } } } @@ -79,6 +91,8 @@ const tabEditor = { searchbar.hide() document.body.classList.remove('is-edit-mode') + document.body.classList.remove('ntp-blur') + searchbar.el.classList.remove('searchbar-hidden') webviews.hidePlaceholder('editMode') }, @@ -94,6 +108,11 @@ const tabEditor = { keyboardNavigationHelper.addToGroup('searchbar', tabEditor.container) tabEditor.input.addEventListener('input', function (e) { + if (newTabPage.hasBackground) { + document.body.classList.add('ntp-blur') + } + searchbar.el.classList.remove('searchbar-hidden') + // handles all inputs except for the case where the selection is moved (since we call preventDefault() there) searchbar.showResults(this.value, { isDeletion: e.inputType.includes('delete') diff --git a/js/newTabPage.js b/js/newTabPage.js index ab7b0f886..e66a6dbe2 100644 --- a/js/newTabPage.js +++ b/js/newTabPage.js @@ -1,5 +1,7 @@ const path = require('path') const statistics = require('js/statistics.js') +const settings = require('util/settings/settings.js') +const webviews = require('webviews.js') const newTabPage = { background: document.getElementById('ntp-background'), @@ -9,6 +11,15 @@ const newTabPage = { imagePath: path.join(window.globalArgs['user-data-path'], 'newTabBackground'), blobInstance: null, reloadBackground: function () { + const newTabUrl = settings.get('newTabUrl') + if (newTabUrl === 'blank') { + newTabPage.background.hidden = true + newTabPage.hasBackground = false + document.body.classList.remove('ntp-has-background') + newTabPage.deleteBackground.hidden = true + return + } + fs.readFile(newTabPage.imagePath, function (err, data) { if (newTabPage.blobInstance) { URL.revokeObjectURL(newTabPage.blobInstance) @@ -32,32 +43,52 @@ const newTabPage = { } }) }, + pickImage: async function () { + var filePath = await ipc.invoke('showOpenDialog', { + filters: [ + { name: 'Image files', extensions: ['jpg', 'jpeg', 'png', 'gif', 'webp'] } + ] + }) + + if (!filePath || filePath.length === 0) { + // User cancelled the file picker - reset to blank if no image was previously set + if (!newTabPage.hasBackground) { + settings.set('newTabUrl', 'blank') + } + return + } + + await fs.promises.copyFile(filePath[0], newTabPage.imagePath) + settings.set('newTabUrl', 'backgroundImage') + newTabPage.reloadBackground() + }, + removeImage: async function () { + await fs.promises.unlink(newTabPage.imagePath) + settings.set('newTabUrl', 'blank') + newTabPage.reloadBackground() + }, initialize: function () { newTabPage.reloadBackground() - newTabPage.picker.addEventListener('click', async function () { - var filePath = await ipc.invoke('showOpenDialog', { - filters: [ - { name: 'Image files', extensions: ['jpg', 'jpeg', 'png', 'gif', 'webp'] } - ] - }) + newTabPage.picker.addEventListener('click', newTabPage.pickImage) - if (!filePath) { - return - } + newTabPage.deleteBackground.addEventListener('click', newTabPage.removeImage) - await fs.promises.copyFile(filePath[0], newTabPage.imagePath) - newTabPage.reloadBackground() + webviews.bindIPC('uploadNewTabBackground', function () { + newTabPage.pickImage() }) - newTabPage.deleteBackground.addEventListener('click', async function () { - await fs.promises.unlink(newTabPage.imagePath) - newTabPage.reloadBackground() + webviews.bindIPC('removeNewTabBackground', function () { + newTabPage.removeImage() }) statistics.registerGetter('ntpHasBackground', function () { return newTabPage.hasBackground }) + + settings.listen('newTabUrl', function (value) { + newTabPage.reloadBackground() + }) } } diff --git a/js/preload/default.js b/js/preload/default.js index 7b767285f..ea9567533 100644 --- a/js/preload/default.js +++ b/js/preload/default.js @@ -61,4 +61,12 @@ window.addEventListener('message', function (e) { if (e.data?.message === 'downloadFile') { ipc.send('downloadFile', e.data.url) } + + if (e.data?.message === 'uploadNewTabBackground') { + ipc.send('uploadNewTabBackground') + } + + if (e.data?.message === 'removeNewTabBackground') { + ipc.send('removeNewTabBackground') + } }) diff --git a/localization/languages/en-US.json b/localization/languages/en-US.json index 6fc6a6c53..29614cce1 100644 --- a/localization/languages/en-US.json +++ b/localization/languages/en-US.json @@ -179,6 +179,12 @@ "settingsStartupCreateTask": "Re-open previous tabs", "settingsStartupNewTaskandBackground": "Move previous tabs to a background task", "settingsStartupNewTaskOnly": "Open a new blank task", + "settingsNewTabUrl": "New Tab Page:", + "settingsNewTabUrlBlank": "Blank Page", + "settingsNewTabUrlCustomUrl": "Custom URL", + "settingsNewTabUrlBackgroundImage": "Background Image", + "settingsNewTabUrlUploadImage": "Upload Image", + "settingsNewTabUrlRemoveImage": "Remove Image", "settingsNewWindowOptions": "In new windows: ", "settingsNewWindowCreateTask": "Create a new task", "settingsNewWindowPickTask": "Show task list", diff --git a/main/menu.js b/main/menu.js index f01e979f3..4e5e3a6c5 100644 --- a/main/menu.js +++ b/main/menu.js @@ -257,24 +257,6 @@ function buildAppMenu (options = {}) { sendIPCToWindow(window, 'zoomOut') } }, - // Hidden item to enable shortcut on numpad - { - label: l('appMenuZoomIn'), - accelerator: 'CmdOrCtrl+numadd', - click: function (item, window) { - sendIPCToWindow(window, 'zoomIn') - }, - visible: false - }, - // Hidden item to enable shortcut on numpad - { - label: l('appMenuZoomOut'), - accelerator: 'CmdOrCtrl+numsub', - click: function (item, window) { - sendIPCToWindow(window, 'zoomOut') - }, - visible: false - }, { label: l('appMenuActualSize'), accelerator: 'CmdOrCtrl+0', diff --git a/pages/settings/index.html b/pages/settings/index.html index d8e6d629c..fc159e5a3 100644 --- a/pages/settings/index.html +++ b/pages/settings/index.html @@ -151,6 +151,21 @@

+
+ + + +
+