diff --git a/package-lock.json b/package-lock.json index 82b8328..a657c49 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2826,6 +2826,11 @@ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true }, + "codemirror": { + "version": "5.49.2", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.49.2.tgz", + "integrity": "sha512-dwJ2HRPHm8w51WB5YTF9J7m6Z5dtkqbU9ntMZ1dqXyFB9IpjoUFDj80ahRVEoVanfIp6pfASJbOlbWdEf8FOzQ==" + }, "collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", @@ -3793,6 +3798,11 @@ "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", "dev": true }, + "diff-match-patch": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.4.tgz", + "integrity": "sha512-Uv3SW8bmH9nAtHKaKSanOQmj2DnlH65fUpcrMdfdaOxUG02QQ4YGZ8AE7kKOMisF7UqvOlGKVYWRvezdncW9lg==" + }, "diffie-hellman": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", @@ -11736,6 +11746,15 @@ "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.10.tgz", "integrity": "sha512-ImThpeNU9HbdZL3utgMCq0oiMzAkt1mcgy3/E6zWC/G6AaQoeuFdsl9nDhTDU3X1R6FK7nsIUuRACVcjI+A2GQ==" }, + "vue-codemirror": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/vue-codemirror/-/vue-codemirror-4.0.6.tgz", + "integrity": "sha512-ilU7Uf0mqBNSSV3KT7FNEeRIxH4s1fmpG4TfHlzvXn0QiQAbkXS9lLfwuZpaBVEnpP5CSE62iGJjoliTuA8poQ==", + "requires": { + "codemirror": "^5.41.0", + "diff-match-patch": "^1.0.0" + } + }, "vue-eslint-parser": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-2.0.3.tgz", diff --git a/package.json b/package.json index c6792c7..10d1973 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "v-clipboard": "^2.2.2", "validator": "^11.1.0", "vue": "^2.5.17", + "vue-codemirror": "^4.0.6", "vue-headful": "^2.0.1", "vue-mq": "^1.0.1", "vue-recaptcha": "^1.1.1", diff --git a/src/components/app/Popouts/Popouts/Settings.vue b/src/components/app/Popouts/Popouts/Settings.vue index f5a151e..38676f6 100644 --- a/src/components/app/Popouts/Popouts/Settings.vue +++ b/src/components/app/Popouts/Popouts/Settings.vue @@ -38,6 +38,7 @@ import isElectron from '@/utils/ElectronJS/isElectron'; const MyProfile = () => import("./SettingsPanels/MyProfile.vue"); const ManageEmojis = () => import("./SettingsPanels/ManageEmojis.vue"); const MessageDesign = () => import("./SettingsPanels/MessageDesign.vue"); +const MyThemes = () => import("./SettingsPanels/MyThemes.vue"); const Notifications = () => import("./SettingsPanels/Notifications.vue"); const AppSettings = () => import("./SettingsPanels/appSettings"); @@ -47,6 +48,7 @@ export default { MyProfile, ManageEmojis, MessageDesign, + MyThemes, Notifications, AppSettings }, @@ -66,6 +68,12 @@ export default { icon: "palette", component: "message-design" }, + { + name: "My Themes", + tabName: "My Themes BETA", + icon: "palette", + component: "my-themes" + }, { name: "Manage Emojis", tabName: "Manage Emojis", diff --git a/src/components/app/Popouts/Popouts/SettingsPanels/MyThemes.vue b/src/components/app/Popouts/Popouts/SettingsPanels/MyThemes.vue new file mode 100644 index 0000000..1b7669f --- /dev/null +++ b/src/components/app/Popouts/Popouts/SettingsPanels/MyThemes.vue @@ -0,0 +1,330 @@ + + + + + + + save + Save + + + clear + Close + + Apply + + + + + warning + Warning: Pasting someone elses code could be dangerous. + + + + + + explore + Explore + + + add + Create + + + + + + + {{ theme.name }} + + + + check + Apply + + + edit + Edit + + + delete + Delete + + + + + + + + + + + + diff --git a/src/services/ThemeService.js b/src/services/ThemeService.js new file mode 100644 index 0000000..65c7b8d --- /dev/null +++ b/src/services/ThemeService.js @@ -0,0 +1,19 @@ +import {instance, wrapper} from './Api'; + +export default { + getTheme (id) { + return wrapper(instance().get(`themes/${id}`)); + }, + getThemes () { + return wrapper(instance().get('themes/')); + }, + save (data) { + return wrapper(instance().post(`themes/`, data)); + }, + update (data, id) { + return wrapper(instance().patch(`themes/${id}`, data)); + }, + delete (id) { + return wrapper(instance().delete(`themes/${id}`)); + }, +} \ No newline at end of file diff --git a/src/utils/changelog.js b/src/utils/changelog.js index 119f360..1d31542 100644 --- a/src/utils/changelog.js +++ b/src/utils/changelog.js @@ -9,12 +9,22 @@ const prototype = { }; const config = [ + { + version: 8.8, + title: "Themes!", + shortTitle: "", + date: "29/11/2019", + headColor: "#007792", + new: [ + "You can now create your own themes in the settings popout using css! (You cannot share themes for now, that feature is coming soon though!)", + ], + + }, { version: 8.7, title: "12 hour clock mode", shortTitle: "", date: "24/11/2019", - headColor: "#007792", new: [ "Added 12 hour clock mode." ], diff --git a/src/views/App.vue b/src/views/App.vue index 8ca1666..ddacef4 100644 --- a/src/views/App.vue +++ b/src/views/App.vue @@ -31,6 +31,7 @@ import changelog from "@/utils/changelog.js"; import ConnectingScreen from "./../components/app/ConnectingScreen.vue"; import Spinner from "./../components/Spinner.vue"; import MainNav from "./../components/app/MainNav.vue"; +import ThemeService from '../services/ThemeService'; const ElectronFrameButtons = () => import("@/components/ElectronJS/FrameButtons.vue"); @@ -121,6 +122,18 @@ export default { const height = dimensions.height; this.$refs.app.style.height = height + "px"; this.$refs.app.style.width = width + "px"; + }, + async setTheme() { + const themeAppliedID = localStorage.getItem('appliedThemeId'); + + + if (!themeAppliedID) {return;} + const {ok, result, error} = await ThemeService.getTheme(themeAppliedID); + if (!ok) { return; } + const styleEl = document.createElement('style'); + styleEl.id = "theme" + styleEl.innerHTML = result.data.css + document.head.innerHTML += styleEl.outerHTML; } }, watch: { @@ -128,7 +141,7 @@ export default { this.resizeEvent(dimensions); } }, - mounted() { + async mounted() { const currentTab = localStorage.getItem("currentTab"); if (currentTab) { this.$store.dispatch("setCurrentTab", parseInt(currentTab)); @@ -143,6 +156,8 @@ export default { bus.$on("title:change", title => { this.title = title; }); + this.setTheme(); + }, computed: {