Import and Export Themes
-
@potmeklecbohdan You should have called it Feces'n'Grapes : P, but it's a nice effort nevertheless.
-
Here's a bunch,
After Eight
{"themeName":"After Eight","themeBg":"18181b","themeFg":"979ea1","themeHi":"5e9194","themeAc":"0d0d0f","themePage":0,"themeWin":1,"themeTabs":0,"themeRound":"2"}
Before Eight
{"themeName":"Before Eight","themeBg":"ffffff","themeFg":"808282","themeHi":"2b8089","themeAc":"d4d4d4","themePage":0,"themeWin":1,"themeTabs":0,"themeRound":"1"}
Black Messa
{"themeName":"Balck Messa","themeBg":"161619","themeFg":"646c6f","themeHi":"ff8905","themeAc":"0d0d0d","themePage":0,"themeWin":1,"themeTabs":0,"themeRound":"2"}
Cyberpunk
{"themeName":"Cyberpunk","themeBg":"080808","themeFg":"2491ac","themeHi":"ec2be6","themeAc":"0d0d0d","themePage":0,"themeWin":1,"themeTabs":1,"themeRound":"7"}
Extension Control
{"themeName":"Extension Control","themeBg":"191919","themeFg":"a5a6aa","themeHi":"92a2e1","themeAc":"131313","themePage":0,"themeWin":1,"themeTabs":0,"themeRound":"3"}
Frostpunk
{"themeName":"Frostpunk","themeBg":"fcfcfc","themeFg":"1c4558","themeHi":"2ba5d8","themeAc":"c1d5e1","themePage":0,"themeWin":1,"themeTabs":0,"themeRound":"3"}
Material
{"themeName":"Material","themeBg":"283339","themeFg":"829aa6","themeHi":"60ffdb","themeAc":"29343b","themePage":0,"themeWin":1,"themeTabs":0,"themeRound":"2"}
Neon Dawn
{"themeName":"Neon Dawn","themeBg":"18181b","themeFg":"646c6f","themeHi":"e566e1","themeAc":"29292e","themePage":0,"themeWin":1,"themeTabs":0,"themeRound":"2"}
New Dawn
{"themeName":"New Dawn","themeBg":"f9faff","themeFg":"858593","themeHi":"ff2fff","themeAc":"eff0f5","themePage":0,"themeWin":1,"themeTabs":1,"themeRound":"0"}
Nflix
{"themeName":"Nflix","themeBg":"141414","themeFg":"949496","themeHi":"d62e36","themeAc":"111111","themePage":0,"themeWin":1,"themeTabs":0,"themeRound":"0"}
Nocturnal
{"themeName":"Nocturnal","themeBg":"1b1919","themeFg":"9f9f9a","themeHi":"a7d129","themeAc":"616f39","themePage":0,"themeWin":1,"themeTabs":0,"themeRound":"3"}
Palenight
{"themeName":"Palenight","themeBg":"292d3e","themeFg":"8187a9","themeHi":"00bcd4","themeAc":"1c1f2b","themePage":0,"themeWin":1,"themeTabs":0,"themeRound":"2"}
Particle
{"themeName":"Particle","themeBg":"fcfcfc","themeFg":"858593","themeHi":"a1a6d4","themeAc":"525260","themePage":0,"themeWin":1,"themeTabs":0,"themeRound":"3"}
Safari
{"themeName":"Safari","themeBg":"f6f6f6","themeFg":"737373","themeHi":"3388fc","themeAc":"cccccc","themePage":0,"themeWin":1,"themeTabs":0,"themeRound":"14"}
Steampunk
{"themeName":"Steampunk","themeBg":"f8f8ed","themeFg":"4f442e","themeHi":"ce4120","themeAc":"422815","themePage":0,"themeWin":1,"themeTabs":0,"themeRound":"0"}
Sunset
{"themeName":"Sunset","themeBg":"572121","themeFg":"ddcbd4","themeHi":"df4d19","themeAc":"a43737","themePage":0,"themeWin":1,"themeTabs":1,"themeRound":"14"}
TWN
{"themeName":"TWN","themeBg":"8fa0b1","themeFg":"fffff8","themeHi":"ffec53","themeAc":"71879c","themePage":0,"themeWin":1,"themeTabs":0,"themeRound":"0"}
-
@sjudenim Great themes, I especially like cyberpunk and material.
-
What follows here is not user friendly and can potentially lose all your user themes in case you mess up somehow. Use at your own risk, although I guarantee it will work out fine, if you handle it correctly.
/* Backup or Import all user themes */ function exportUserThemes() { chrome.storage.local.get({'THEMES_USER': ''}, function(xp) { const userThemes = xp.THEMES_USER; const themeCode = JSON.stringify(userThemes); navigator.clipboard.writeText(themeCode); console.log('All user themes have been copied to clipboard. Paste the code for backup and remove this modification from your active setup.') }); }; function importUserThemes() { const themeCode = ''; /* Paste your backup here */ const userThemes = JSON.parse(themeCode); chrome.storage.local.set({'THEMES_USER': userThemes}, function() { console.log('All user themes have been imported. This action has overwritten all your current themes, I hope you have been careful. Remove this modification from your active setup.'); }); }; setTimeout(function wait() { const browser = document.getElementById('browser'); if (browser) { /* Activate import or export function here, open a new browser window to run and then remove this entry again */ } else { setTimeout(wait, 300); } }, 300);
-
And a version of the above that can be run directly from the console:
/* Backup */ chrome.storage.local.get({'THEMES_USER': ''}, function(xp) { const userThemes = xp.THEMES_USER; const themeCode = JSON.stringify(userThemes); console.log(themeCode); console.log('Copy and paste to backup.') }); /* Import */ const themeCode = ''; const userThemes = JSON.parse(themeCode); chrome.storage.local.set({'THEMES_USER': userThemes}, function() { console.log('User themes imported.'); });
-
I have added an import test function to avoid unintended errors
function checkUserThemes(userThemes) { if (Array.isArray(userThemes)) { for (let i = 0; i < userThemes.length; i++) { const theme = userThemes[i]; if ( typeof theme.colors !== 'object' || typeof theme.colors.accentBg !== 'string' || !/^#(?:[0-9a-f]{3}){1,2}$/i.test(theme.colors.accentBg) || typeof theme.colors.baseBg !== 'string' || !/^#(?:[0-9a-f]{3}){1,2}$/i.test(theme.colors.baseBg) || typeof theme.colors.baseFg !== 'string' || !/^#(?:[0-9a-f]{3}){1,2}$/i.test(theme.colors.baseFg) || typeof theme.colors.highlightBg !== 'string' || !/^#(?:[0-9a-f]{3}){1,2}$/i.test(theme.colors.highlightBg) || typeof theme.name !== 'string' || typeof theme.settings !== 'object' || typeof theme.settings.accentFromPage !== 'boolean' || typeof theme.settings.accentOnWindow !== 'boolean' || (typeof theme.settings.borderRadius !== 'number' && typeof theme.settings.borderRadius !== 'string') || typeof theme.settings.tabsTransparent !== 'boolean' || typeof theme.version !== 'number' ) { return false; } } return true; } else { return false; } }
-
@tam710562 Can't hurt. To be honest not much can go wrong when you have correctly backed up theme code. The import can just be tried again in case something goes wrong – after all the themes are just an array in local storage.
-
I updated the mod, it's working again in latest snapshot. Do not update this mod on stable 2.3.
And yeah, please let me know should you have issues. I tested exporting and importing and it seems to be fine, but you can never know…
-
@luetage said in Import and Export Themes:
@tam710562 Can't hurt. To be honest not much can go wrong when you have correctly backed up theme code. The import can just be tried again in case something goes wrong – after all the themes are just an array in local storage.
I'm eating my own words right now. Much can go wrong.
Yesterday I lost one of my themes while exporting and overwriting it in my notes, because Vivaldi still has the bug that clicking on another theme won't change the theme colors in the edit view. Since this mod reads from the input fields, the theme was lost. Rest in peace, Goldfish theme.
This casualty angered me greatly and I decided to rewrite the mod from ground up, this time independent from theme inputs and solely relying on changing the local storage directly. I had jolly good fun, until I tested a compatibility function, which resulted in Vivaldi losing the UI and freezing up completely – couldn't bring it back until I deleted the local app settings, which just goes to show @tam710562's import test function is a godsend when messing with Vivaldi's storage.
Anyway, about the new version…
Features
- Export selected theme. Click Export button and paste theme code to notes panel. Or store it anywhere really, but notes have sync!!
- Import selected theme. Paste or drag&drop theme code to import input field.
- Backup all user themes.
alt-click
on Export button – this will copy the whole user themes object from local storage. - Restore all user themes. Paste or drag&drop a previous backup on import input field. The mod will automatically recognise it as a backup and restore it. Warning: Restoring from a backup will delete all your current user themes! You have to confirm this action before it will trigger.
The mod is backwards compatible with the themes you have already backed up and with the themes that have been shared/posted, but it will export the theme codes in the native Vivaldi format from now on. @tam710562's import test function is part of both the theme import and theme restore functionality – in theory nothing should go wrong and I have tested it extensively in practice too, but I'd still advise you to backup your profile folder before trying it out, just to be completely safe. I'll put the mod in OP in a few days when I can be 100% certain that it works perfectly. Until then, you can copy or download the mod from github:
https://github.com/luetage/vivaldi_modding/blob/master/import-export_themes.js
Please test and report back, feedback appreciated!
-
@luetage tested the new js, backed up 3 themes in notes, deleted them all and restored them with no problems.
-
For me the same as @iAN-CooG — everything OK. Don't you think it'd be also good to create new theme when importing, or at least ask if user wants to overwrite current one?
-
@potmeklecbohdan It's possible to rewrite the code to make a new theme instead of overwriting the current one, I'm fine with it either way. It's the way it is because we click Edit Theme or Add Theme to access the buttons, therefore it should be clear it will overwrite the selected theme. Don't know how I feel about the choice in UI, would probably need an extra button and it takes another click… and adding a theme yourself only takes another click too – so both options together are probably not happening.
-
New version up on github. The import of backups is non-destructive now. It will add to your existing themes instead of overwriting everything. This means we can share theme collections with one another, just as @sjudenim has done above. I took the freedom to collect his themes in one easy to import backup as example:
sjudenim's theme collection
[{"colors":{"accentBg":"#0d0d0f","baseBg":"#18181b","baseFg":"#979ea1","highlightBg":"#5e9194"},"name":"After Eight","settings":{"accentFromPage":false,"accentOnWindow":true,"borderRadius":"2","tabsTransparent":false},"version":0.1},{"colors":{"accentBg":"#d4d4d4","baseBg":"#ffffff","baseFg":"#808282","highlightBg":"#2b8089"},"name":"Before Eight","settings":{"accentFromPage":false,"accentOnWindow":true,"borderRadius":"1","tabsTransparent":false},"version":0.1},{"colors":{"accentBg":"#0d0d0d","baseBg":"#161619","baseFg":"#646c6f","highlightBg":"#ff8905"},"name":"Black Messa","settings":{"accentFromPage":false,"accentOnWindow":true,"borderRadius":"2","tabsTransparent":false},"version":0.1},{"colors":{"accentBg":"#0d0d0d","baseBg":"#080808","baseFg":"#2491ac","highlightBg":"#ec2be6"},"name":"Cyberpunk","settings":{"accentFromPage":false,"accentOnWindow":true,"borderRadius":"7","tabsTransparent":true},"version":0.1},{"colors":{"accentBg":"#131313","baseBg":"#191919","baseFg":"#a5a6aa","highlightBg":"#92a2e1"},"name":"Extension Control","settings":{"accentFromPage":false,"accentOnWindow":true,"borderRadius":"3","tabsTransparent":false},"version":0.1},{"colors":{"accentBg":"#c1d5e1","baseBg":"#fcfcfc","baseFg":"#1c4558","highlightBg":"#2ba5d8"},"name":"Frostpunk","settings":{"accentFromPage":false,"accentOnWindow":true,"borderRadius":"3","tabsTransparent":false},"version":0.1},{"colors":{"accentBg":"#29343b","baseBg":"#283339","baseFg":"#829aa6","highlightBg":"#60ffdb"},"name":"Material","settings":{"accentFromPage":false,"accentOnWindow":true,"borderRadius":"2","tabsTransparent":false},"version":0.1},{"colors":{"accentBg":"#29292e","baseBg":"#18181b","baseFg":"#646c6f","highlightBg":"#e566e1"},"name":"Neon Dawn","settings":{"accentFromPage":false,"accentOnWindow":true,"borderRadius":"2","tabsTransparent":false},"version":0.1},{"colors":{"accentBg":"#eff0f5","baseBg":"#f9faff","baseFg":"#858593","highlightBg":"#ff2fff"},"name":"New Dawn","settings":{"accentFromPage":false,"accentOnWindow":true,"borderRadius":"0","tabsTransparent":true},"version":0.1},{"colors":{"accentBg":"#111111","baseBg":"#141414","baseFg":"#949496","highlightBg":"#d62e36"},"name":"Nflix","settings":{"accentFromPage":false,"accentOnWindow":true,"borderRadius":"0","tabsTransparent":false},"version":0.1},{"colors":{"accentBg":"#616f39","baseBg":"#1b1919","baseFg":"#9f9f9a","highlightBg":"#a7d129"},"name":"Nocturnal","settings":{"accentFromPage":false,"accentOnWindow":true,"borderRadius":"3","tabsTransparent":false},"version":0.1},{"colors":{"accentBg":"#1c1f2b","baseBg":"#292d3e","baseFg":"#8187a9","highlightBg":"#00bcd4"},"name":"Palenight","settings":{"accentFromPage":false,"accentOnWindow":true,"borderRadius":"2","tabsTransparent":false},"version":0.1},{"colors":{"accentBg":"#525260","baseBg":"#fcfcfc","baseFg":"#858593","highlightBg":"#a1a6d4"},"name":"Particle","settings":{"accentFromPage":false,"accentOnWindow":true,"borderRadius":"3","tabsTransparent":false},"version":0.1},{"colors":{"accentBg":"#cccccc","baseBg":"#f6f6f6","baseFg":"#737373","highlightBg":"#3388fc"},"name":"Safari","settings":{"accentFromPage":false,"accentOnWindow":true,"borderRadius":"14","tabsTransparent":false},"version":0.1},{"colors":{"accentBg":"#422815","baseBg":"#f8f8ed","baseFg":"#4f442e","highlightBg":"#ce4120"},"name":"Steampunk","settings":{"accentFromPage":false,"accentOnWindow":true,"borderRadius":"0","tabsTransparent":false},"version":0.1},{"colors":{"accentBg":"#a43737","baseBg":"#572121","baseFg":"#ddcbd4","highlightBg":"#df4d19"},"name":"Sunset","settings":{"accentFromPage":false,"accentOnWindow":true,"borderRadius":"14","tabsTransparent":true},"version":0.1},{"colors":{"accentBg":"#71879c","baseBg":"#8fa0b1","baseFg":"#fffff8","highlightBg":"#ffec53"},"name":"TWN","settings":{"accentFromPage":false,"accentOnWindow":true,"borderRadius":"0","tabsTransparent":false},"version":0.1}]
I also did extensive testing of the mod and as far as I can tell it's failsafe now. You could paste your grandmother and Vivaldi's storage would survive
Also there is new functionality in this version, an upvote to anyone who finds it. I'm open to more suggestions, but I think it's quite presentable/useable as is.
-
@luetage Hi, i've been trying it for a while and it seems to me to be working fine.
I'm sorry, but the appetite comes from eating, you could do something like that for search engines as well?
-
@luetage said in Import and Export Themes:
Also there is new functionality in this version, an upvote to anyone who finds it.
Shift click import to sort user themes?
-
@Folgore101 Sure, that's no problem – it's the same thing really, and it's easier, because we don't have a use for sharing engines or exporting individual ones. I just don't think it's particularly useful to make buttons in the UI for it – this can simply be done from the console.
@iAN-CooG Finally! Just change import to export and you're spot on
-
@luetage right, I wrote the exact opposite of what I meant. Damn I'm good at reading
-
The latest version adds buttons to the UI to move a selected user theme to the left or to the right. It's up on Github, but I also edited OP of this topic with explanations and features rundown and latest code. Official release time!
-
@luetage said in Import and Export Themes:
@Folgore101 Sure, that's no problem – it's the same thing really, and it's easier, because we don't have a use for sharing engines or exporting individual ones. I just don't think it's particularly useful to make buttons in the UI for it – this can simply be done from the console.
How? I right-click on a page and click on Inspect, Console and then what do I do?
I'm sorry, but it's only recently that i follow the Customizations section and i'm not very experienced, even doing a search i have not found any useful information. -
@Folgore101 You have to inspect Vivaldi's UI. Then you just paste and execute code in console – that I haven't written yet.
But hey, doesn't hurt to do an individual mod for this, I already know how to do these buttons anyway. Will take some time, since I gotta go now.