aboutsummaryrefslogtreecommitdiffstats
path: root/apps/theming/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'apps/theming/src/components')
-rw-r--r--apps/theming/src/components/AppOrderSelectorElement.vue2
-rw-r--r--apps/theming/src/components/BackgroundSettings.vue58
-rw-r--r--apps/theming/src/components/ItemPreview.vue27
-rw-r--r--apps/theming/src/components/UserAppMenuSection.vue31
-rw-r--r--apps/theming/src/components/UserPrimaryColor.vue14
-rw-r--r--apps/theming/src/components/admin/AppMenuSection.vue14
-rw-r--r--apps/theming/src/components/admin/CheckboxField.vue14
-rw-r--r--apps/theming/src/components/admin/ColorPickerField.vue14
-rw-r--r--apps/theming/src/components/admin/FileInputField.vue14
-rw-r--r--apps/theming/src/components/admin/TextField.vue2
10 files changed, 71 insertions, 119 deletions
diff --git a/apps/theming/src/components/AppOrderSelectorElement.vue b/apps/theming/src/components/AppOrderSelectorElement.vue
index 6336173f97a..fc41e8e6165 100644
--- a/apps/theming/src/components/AppOrderSelectorElement.vue
+++ b/apps/theming/src/components/AppOrderSelectorElement.vue
@@ -65,7 +65,7 @@ import { defineComponent, nextTick, ref } from 'vue'
import IconArrowDown from 'vue-material-design-icons/ArrowDown.vue'
import IconArrowUp from 'vue-material-design-icons/ArrowUp.vue'
-import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
+import NcButton from '@nextcloud/vue/components/NcButton'
interface IApp {
id: string // app id
diff --git a/apps/theming/src/components/BackgroundSettings.vue b/apps/theming/src/components/BackgroundSettings.vue
index 6368f0958d5..58b76dd9602 100644
--- a/apps/theming/src/components/BackgroundSettings.vue
+++ b/apps/theming/src/components/BackgroundSettings.vue
@@ -78,25 +78,22 @@
</template>
<script>
-import { generateFilePath, generateRemoteUrl, generateUrl } from '@nextcloud/router'
-import { getCurrentUser } from '@nextcloud/auth'
+import { generateFilePath, generateUrl } from '@nextcloud/router'
import { getFilePickerBuilder, showError } from '@nextcloud/dialogs'
import { loadState } from '@nextcloud/initial-state'
-import { Palette } from 'node-vibrant/lib/color.js'
import axios from '@nextcloud/axios'
import debounce from 'debounce'
-import NcColorPicker from '@nextcloud/vue/dist/Components/NcColorPicker.js'
-import Vibrant from 'node-vibrant'
+import NcColorPicker from '@nextcloud/vue/components/NcColorPicker'
import Check from 'vue-material-design-icons/Check.vue'
import ImageEdit from 'vue-material-design-icons/ImageEdit.vue'
-import ColorPalette from 'vue-material-design-icons/Palette.vue'
+import ColorPalette from 'vue-material-design-icons/PaletteOutline.vue'
const shippedBackgroundList = loadState('theming', 'shippedBackgrounds')
const backgroundImage = loadState('theming', 'userBackgroundImage')
const {
backgroundImage: defaultBackgroundImage,
- backgroundColor: defaultBackgroundColor,
+ // backgroundColor: defaultBackgroundColor,
backgroundMime: defaultBackgroundMime,
defaultShippedBackground,
} = loadState('theming', 'themingDefaults')
@@ -217,9 +214,9 @@ export default {
this.update(result.data)
},
- async setFile(path, color = null) {
+ async setFile(path) {
this.loading = 'custom'
- const result = await axios.post(generateUrl('/apps/theming/background/custom'), { value: path, color })
+ const result = await axios.post(generateUrl('/apps/theming/background/custom'), { value: path })
this.update(result.data)
},
@@ -237,7 +234,7 @@ export default {
debouncePickColor: debounce(function(...args) {
this.pickColor(...args)
- }, 200),
+ }, 1000),
pickFile() {
const picker = getFilePickerBuilder(t('theming', 'Select a background from your files'))
@@ -264,45 +261,7 @@ export default {
}
this.loading = 'custom'
-
- // Extract primary color from image
- let response = null
- let color = null
- try {
- const fileUrl = generateRemoteUrl('dav/files/' + getCurrentUser().uid + path)
- response = await axios.get(fileUrl, { responseType: 'blob' })
- const blobUrl = URL.createObjectURL(response.data)
- const palette = await this.getColorPaletteFromBlob(blobUrl)
-
- // DarkVibrant is accessible AND visually pleasing
- // Vibrant is not accessible enough and others are boring
- color = palette?.DarkVibrant?.hex
- this.setFile(path, color)
-
- // Log data
- console.debug('Extracted colour', color, 'from custom image', path, palette)
- } catch (error) {
- this.setFile(path)
- console.error('Unable to extract colour from custom image', { error, path, response, color })
- }
- },
-
- /**
- * Extract a Vibrant color palette from a blob URL
- *
- * @param {string} blobUrl the blob URL
- * @return {Promise<Palette>}
- */
- getColorPaletteFromBlob(blobUrl) {
- return new Promise((resolve, reject) => {
- const vibrant = new Vibrant(blobUrl)
- vibrant.getPalette((error, palette) => {
- if (error) {
- reject(error)
- }
- resolve(palette)
- })
- })
+ this.setFile(path)
},
},
}
@@ -339,7 +298,6 @@ export default {
background-size: cover;
&__filepicker {
- background-color: var(--color-main-text);
background-color: var(--color-background-dark);
&.background--active {
diff --git a/apps/theming/src/components/ItemPreview.vue b/apps/theming/src/components/ItemPreview.vue
index 1e34d947d7d..e4a1acd3e2a 100644
--- a/apps/theming/src/components/ItemPreview.vue
+++ b/apps/theming/src/components/ItemPreview.vue
@@ -7,11 +7,16 @@
<div class="theming__preview-image" :style="{ backgroundImage: 'url(' + img + ')' }" @click="onToggle" />
<div class="theming__preview-description">
<h3>{{ theme.title }}</h3>
- <p class="theming__preview-explanation">{{ theme.description }}</p>
+ <p class="theming__preview-explanation">
+ {{ theme.description }}
+ </p>
<span v-if="enforced" class="theming__preview-warning" role="note">
{{ t('theming', 'Theme selection is enforced') }}
</span>
- <NcCheckboxRadioSwitch class="theming__preview-toggle"
+
+ <!-- Only show checkbox if we can change themes -->
+ <NcCheckboxRadioSwitch v-show="!enforced"
+ class="theming__preview-toggle"
:checked.sync="checked"
:disabled="enforced"
:name="name"
@@ -24,7 +29,7 @@
<script>
import { generateFilePath } from '@nextcloud/router'
-import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js'
+import NcCheckboxRadioSwitch from '@nextcloud/vue/components/NcCheckboxRadioSwitch'
export default {
name: 'ItemPreview',
@@ -71,6 +76,10 @@ export default {
return this.selected
},
set(checked) {
+ if (this.enforced) {
+ return
+ }
+
console.debug('Changed theme', this.theme.id, checked)
// If this is a radio, we can only enable
@@ -87,6 +96,10 @@ export default {
methods: {
onToggle() {
+ if (this.enforced) {
+ return
+ }
+
if (this.switchType === 'radio') {
this.checked = true
return
@@ -104,11 +117,9 @@ export default {
.theming__preview {
// We make previews on 16/10 screens
--ratio: 16;
-
position: relative;
display: flex;
justify-content: flex-start;
- max-width: 800px;
&,
* {
@@ -119,7 +130,7 @@ export default {
flex-basis: calc(16px * var(--ratio));
flex-shrink: 0;
height: calc(10px * var(--ratio));
- margin-right: var(--gap);
+ margin-inline-end: var(--gap);
cursor: pointer;
border-radius: var(--border-radius);
background-repeat: no-repeat;
@@ -145,10 +156,6 @@ export default {
}
}
- &--default {
- grid-column: span 2;
- }
-
&-warning {
color: var(--color-warning);
}
diff --git a/apps/theming/src/components/UserAppMenuSection.vue b/apps/theming/src/components/UserAppMenuSection.vue
index b3d9d9f7694..d4221190f6b 100644
--- a/apps/theming/src/components/UserAppMenuSection.vue
+++ b/apps/theming/src/components/UserAppMenuSection.vue
@@ -33,6 +33,7 @@
<script lang="ts">
import type { IApp } from './AppOrderSelector.vue'
+import type { INavigationEntry } from '../../../../core/src/types/navigation.d.ts'
import { showError } from '@nextcloud/dialogs'
import { loadState } from '@nextcloud/initial-state'
@@ -43,29 +44,9 @@ import { computed, defineComponent, ref } from 'vue'
import axios from '@nextcloud/axios'
import AppOrderSelector from './AppOrderSelector.vue'
import IconUndo from 'vue-material-design-icons/Undo.vue'
-import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
-import NcNoteCard from '@nextcloud/vue/dist/Components/NcNoteCard.js'
-import NcSettingsSection from '@nextcloud/vue/dist/Components/NcSettingsSection.js'
-
-/** See NavigationManager */
-interface INavigationEntry {
- /** Navigation id */
- id: string
- /** Order where this entry should be shown */
- order: number
- /** Target of the navigation entry */
- href: string
- /** The icon used for the naviation entry */
- icon: string
- /** Type of the navigation entry ('link' vs 'settings') */
- type: 'link' | 'settings'
- /** Localized name of the navigation entry */
- name: string
- /** Whether this is the default app */
- default?: boolean
- /** App that registered this navigation entry (not necessarly the same as the id) */
- app?: string
-}
+import NcButton from '@nextcloud/vue/components/NcButton'
+import NcNoteCard from '@nextcloud/vue/components/NcNoteCard'
+import NcSettingsSection from '@nextcloud/vue/components/NcSettingsSection'
/** The app order user setting */
type IAppOrder = Record<string, { order: number, app?: string }>
@@ -98,9 +79,9 @@ export default defineComponent({
/**
* Array of all available apps, it is set by a core controller for the app menu, so it is always available
*/
- const initialAppOrder = Object.values(loadState<Record<string, INavigationEntry>>('core', 'apps'))
+ const initialAppOrder = loadState<INavigationEntry[]>('core', 'apps')
.filter(({ type }) => type === 'link')
- .map((app) => ({ ...app, label: app.name, default: app.default && app.app === enforcedDefaultApp }))
+ .map((app) => ({ ...app, label: app.name, default: app.default && app.id === enforcedDefaultApp }))
/**
* Check if a custom app order is used or the default is shown
diff --git a/apps/theming/src/components/UserPrimaryColor.vue b/apps/theming/src/components/UserPrimaryColor.vue
index 7adfabecddd..f10b8a01825 100644
--- a/apps/theming/src/components/UserPrimaryColor.vue
+++ b/apps/theming/src/components/UserPrimaryColor.vue
@@ -31,14 +31,14 @@ import { loadState } from '@nextcloud/initial-state'
import { translate as t } from '@nextcloud/l10n'
import { generateOcsUrl } from '@nextcloud/router'
import { colord } from 'colord'
-import { debounce } from 'debounce'
import { defineComponent } from 'vue'
-
import axios from '@nextcloud/axios'
-import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
-import NcColorPicker from '@nextcloud/vue/dist/Components/NcColorPicker.js'
-import NcLoadingIcon from '@nextcloud/vue/dist/Components/NcLoadingIcon.js'
-import IconColorPalette from 'vue-material-design-icons/Palette.vue'
+import debounce from 'debounce'
+
+import NcButton from '@nextcloud/vue/components/NcButton'
+import NcColorPicker from '@nextcloud/vue/components/NcColorPicker'
+import NcLoadingIcon from '@nextcloud/vue/components/NcLoadingIcon'
+import IconColorPalette from 'vue-material-design-icons/PaletteOutline.vue'
import IconUndo from 'vue-material-design-icons/UndoVariant.vue'
const { primaryColor, defaultPrimaryColor } = loadState('theming', 'data', { primaryColor: '#0082c9', defaultPrimaryColor: '#0082c9' })
@@ -69,7 +69,7 @@ export default defineComponent({
},
debouncedOnUpdate() {
- return debounce(this.onUpdate, 500)
+ return debounce(this.onUpdate, 1000)
},
},
diff --git a/apps/theming/src/components/admin/AppMenuSection.vue b/apps/theming/src/components/admin/AppMenuSection.vue
index 2bcb6903bdc..bf229f15df4 100644
--- a/apps/theming/src/components/admin/AppMenuSection.vue
+++ b/apps/theming/src/components/admin/AppMenuSection.vue
@@ -30,6 +30,8 @@
</template>
<script lang="ts">
+import type { INavigationEntry } from '../../../../../core/src/types/navigation'
+
import { showError } from '@nextcloud/dialogs'
import { loadState } from '@nextcloud/initial-state'
import { translate as t } from '@nextcloud/l10n'
@@ -38,9 +40,9 @@ import { computed, defineComponent } from 'vue'
import axios from '@nextcloud/axios'
-import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js'
-import NcSelect from '@nextcloud/vue/dist/Components/NcSelect.js'
-import NcSettingsSection from '@nextcloud/vue/dist/Components/NcSettingsSection.js'
+import NcCheckboxRadioSwitch from '@nextcloud/vue/components/NcCheckboxRadioSwitch'
+import NcSelect from '@nextcloud/vue/components/NcSelect'
+import NcSettingsSection from '@nextcloud/vue/components/NcSettingsSection'
import AppOrderSelector from '../AppOrderSelector.vue'
export default defineComponent({
@@ -75,9 +77,8 @@ export default defineComponent({
/**
* All enabled apps which can be navigated
*/
- const allApps = Object.values(
- loadState<Record<string, { id: string, name?: string, icon: string }>>('core', 'apps'),
- ).map(({ id, name, icon }) => ({ label: name, id, icon }))
+ const allApps = loadState<INavigationEntry[]>('core', 'apps')
+ .map(({ id, name, icon }) => ({ label: name, id, icon }))
/**
* Currently selected app, wrapps the setter
@@ -114,6 +115,7 @@ export default defineComponent({
h3, h4 {
font-weight: bold;
}
+
h4, h5 {
margin-block-start: 12px;
}
diff --git a/apps/theming/src/components/admin/CheckboxField.vue b/apps/theming/src/components/admin/CheckboxField.vue
index 17886189f51..42d86ded4e7 100644
--- a/apps/theming/src/components/admin/CheckboxField.vue
+++ b/apps/theming/src/components/admin/CheckboxField.vue
@@ -7,15 +7,17 @@
<div class="field">
<label :for="id">{{ displayName }}</label>
<div class="field__row">
- <NcCheckboxRadioSwitch type="switch"
- :id="id"
+ <NcCheckboxRadioSwitch :id="id"
+ type="switch"
:checked.sync="localValue"
@update:checked="save">
{{ label }}
</NcCheckboxRadioSwitch>
</div>
- <p class="field__description">{{ description }}</p>
+ <p class="field__description">
+ {{ description }}
+ </p>
<NcNoteCard v-if="errorMessage"
type="error"
@@ -26,8 +28,8 @@
</template>
<script>
-import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js'
-import NcNoteCard from '@nextcloud/vue/dist/Components/NcNoteCard.js'
+import NcCheckboxRadioSwitch from '@nextcloud/vue/components/NcCheckboxRadioSwitch'
+import NcNoteCard from '@nextcloud/vue/components/NcNoteCard'
import TextValueMixin from '../../mixins/admin/TextValueMixin.js'
@@ -73,7 +75,7 @@ export default {
</script>
<style lang="scss" scoped>
-@import './shared/field.scss';
+@use './shared/field' as *;
.field {
&__description {
diff --git a/apps/theming/src/components/admin/ColorPickerField.vue b/apps/theming/src/components/admin/ColorPickerField.vue
index e7c7d7bf8ce..4ec6d47fef6 100644
--- a/apps/theming/src/components/admin/ColorPickerField.vue
+++ b/apps/theming/src/components/admin/ColorPickerField.vue
@@ -48,12 +48,13 @@
</template>
<script>
-import { debounce } from 'debounce'
import { colord } from 'colord'
-import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
-import NcColorPicker from '@nextcloud/vue/dist/Components/NcColorPicker.js'
-import NcLoadingIcon from '@nextcloud/vue/dist/Components/NcLoadingIcon.js'
-import NcNoteCard from '@nextcloud/vue/dist/Components/NcNoteCard.js'
+import debounce from 'debounce'
+
+import NcButton from '@nextcloud/vue/components/NcButton'
+import NcColorPicker from '@nextcloud/vue/components/NcColorPicker'
+import NcLoadingIcon from '@nextcloud/vue/components/NcLoadingIcon'
+import NcNoteCard from '@nextcloud/vue/components/NcNoteCard'
import Undo from 'vue-material-design-icons/UndoVariant.vue'
import Palette from 'vue-material-design-icons/Palette.vue'
@@ -135,7 +136,8 @@ export default {
</script>
<style lang="scss" scoped>
-@import './shared/field.scss';
+@use './shared/field' as *;
+
.description {
color: var(--color-text-maxcontrast);
}
diff --git a/apps/theming/src/components/admin/FileInputField.vue b/apps/theming/src/components/admin/FileInputField.vue
index 717f222abbf..d5e0052f5bd 100644
--- a/apps/theming/src/components/admin/FileInputField.vue
+++ b/apps/theming/src/components/admin/FileInputField.vue
@@ -7,8 +7,8 @@
<div class="field">
<label :for="id">{{ displayName }}</label>
<div class="field__row">
- <NcButton type="secondary"
- :id="id"
+ <NcButton :id="id"
+ type="secondary"
:aria-label="ariaLabel"
data-admin-theming-setting-file-picker
@click="activateLocalFilePicker">
@@ -65,10 +65,10 @@ import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router'
import { loadState } from '@nextcloud/initial-state'
-import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
-import NcLoadingIcon from '@nextcloud/vue/dist/Components/NcLoadingIcon.js'
-import NcNoteCard from '@nextcloud/vue/dist/Components/NcNoteCard.js'
-import Delete from 'vue-material-design-icons/Delete.vue'
+import NcButton from '@nextcloud/vue/components/NcButton'
+import NcLoadingIcon from '@nextcloud/vue/components/NcLoadingIcon'
+import NcNoteCard from '@nextcloud/vue/components/NcNoteCard'
+import Delete from 'vue-material-design-icons/DeleteOutline.vue'
import Undo from 'vue-material-design-icons/UndoVariant.vue'
import Upload from 'vue-material-design-icons/Upload.vue'
@@ -209,7 +209,7 @@ export default {
</script>
<style lang="scss" scoped>
-@import './shared/field.scss';
+@use './shared/field' as *;
.field {
&__loading-icon {
diff --git a/apps/theming/src/components/admin/TextField.vue b/apps/theming/src/components/admin/TextField.vue
index b06676a3b20..6ec52733aed 100644
--- a/apps/theming/src/components/admin/TextField.vue
+++ b/apps/theming/src/components/admin/TextField.vue
@@ -23,7 +23,7 @@
</template>
<script>
-import NcTextField from '@nextcloud/vue/dist/Components/NcTextField.js'
+import NcTextField from '@nextcloud/vue/components/NcTextField'
import TextValueMixin from '../../mixins/admin/TextValueMixin.js'