Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion lib/Db/Preferences.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ class Preferences extends Entity implements JsonSerializable {
public const DEFAULT = [
'useCommentsAlternativeStyling' => false,
'useAlternativeStyling' => false,
'useCardsArrangement' => false,
'calendarPeek' => false,
'checkCalendars' => [],
'checkCalendarsHoursBefore' => 0,
Expand Down
5 changes: 4 additions & 1 deletion src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,14 @@ onUnmounted(() => {
row-gap: 8px;

.clamped {
display: -webkit-box !important;
-webkit-line-clamp: 2;
line-clamp: 2;
-webkit-box-orient: vertical;
text-wrap: wrap;
display: -webkit-box;
overflow: clip !important;
text-overflow: ellipsis !important;
padding: 0 !important;
}
}

Expand Down
1 change: 1 addition & 0 deletions src/components/Base/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ export { default as IntersectionObserver } from './modules/IntersectionObserver.
export { default as LoadingOverlay } from './modules/LoadingOverlay.vue'
export { default as QrModal } from './modules/QrModal.vue'
export { default as RadioGroupDiv } from './modules/RadioGroupDiv.vue'
export { default as Collapsible } from './modules/Collapsible.vue'
149 changes: 149 additions & 0 deletions src/components/Base/modules/Collapsible.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
<!--
- SPDX-FileCopyrightText: 2018 Nextcloud contributors
- SPDX-License-Identifier: AGPL-3.0-or-later
-->

<script setup lang="ts">
import { t } from '@nextcloud/l10n'
import { ref } from 'vue'

const props = defineProps({
initialCollapsed: {
type: Boolean,
default: false,
},
showMoreCaption: {
type: String,
default: t('polls', 'Show more'),
},
closeCaption: {
type: String,
default: t('polls', 'Collapse'),
},
noCollapse: {
type: Boolean,
default: false,
},
})

const showMore = ref(!props.initialCollapsed || props.noCollapse)
</script>

<template>
<div class="collapsible">
<div
id="collapsible_container"
:class="['collapsible_container', { open: showMore || noCollapse }]">
<slot />
</div>
<div
v-show="!noCollapse"
:class="['collapsible-toggle', { open: showMore }]"
@click="showMore = !showMore">
{{ showMore ? props.closeCaption : props.showMoreCaption }}
</div>
</div>
</template>

<style lang="scss">
.collapsible {
overflow: hidden;

.collapsible-toggle {
cursor: pointer;
position: relative;
line-height: 2rem;
font-weight: bold;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
background-color: var(--color-background-plain);
color: var(--color-primary-element-text);
border-radius: var(--border-radius-element);

&::before {
content: '\25B8';
margin: 0 0.3em;
display: inline-block;
transform: rotate(90deg);
transition: transform 0.3s ease-in-out;
}
&.open {
&::before {
transform: rotate(-90deg);
}
}
}

.collapsible_container {
transition: max-height 0.3s ease-in-out;
overflow: auto;
max-height: 0;

background:
/* Shadow covers */
linear-gradient(
var(--color-main-background) 30%,
rgba(from var(--color-main-text) r g b / 0)
),
linear-gradient(
rgba(from var(--color-main-text) r g b / 0),
var(--color-main-background) 70%
)
0 100%,
/* Shadows */
radial-gradient(
50% 0,
farthest-side,
rgba(from var(--color-main-text) r g b / 0.2),
rgba(from var(--color-main-background) r g b / 0.2)
),
radial-gradient(
50% 100%,
farthest-side,
rgba(from var(--color-main-text) r g b / 0.2),
rgba(from var(--color-main-background) r g b / 0.2)
)
0 100%;

background:
/* Shadow covers */
linear-gradient(
var(--color-main-background) 30%,
rgba(from var(--color-main-text) r g b / 0)
),
linear-gradient(
rgba(from var(--color-main-text) r g b / 0),
var(--color-main-background) 70%
)
0 100%,
/* Shadows */
radial-gradient(
farthest-side at 50% 0,
rgba(from var(--color-main-text) r g b / 0.2),
rgba(from var(--color-main-background) r g b / 0.2)
),
radial-gradient(
farthest-side at 50% 100%,
rgba(from var(--color-main-text) r g b / 0.2),
rgba(from var(--color-main-background) r g b / 0.2)
)
0 100%;
background-repeat: no-repeat;
background-color: var(--color-main-background);
background-size:
100% 40px,
100% 40px,
100% 14px,
100% 14px;

/* Opera doesn't support this in the shorthand */
background-attachment: local, local, scroll, scroll;

&.open {
max-height: max(51vh, 6rem);
}
}
}
</style>
11 changes: 4 additions & 7 deletions src/components/Base/modules/HeaderBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -83,19 +83,16 @@ function toggleClamp() {
font-weight: bold;
font-size: 1em;
line-height: 1.5em;
overflow: clip;
text-overflow: ellipsis;
display: -webkit-box;
}

.sub {
display: flex;
flex-wrap: wrap;
}
.header_bar_bottom {
display: flex;
margin-bottom: 16px;
}
}

.header_bar_bottom {
margin-bottom: 1rem;
}

[class*='bar_'] {
Expand Down
24 changes: 15 additions & 9 deletions src/components/Poll/MarkUpDescription.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,24 @@

<template>
<!-- eslint-disable-next-line vue/no-v-html -->
<div class="markup-description" v-html="pollStore.descriptionMarkUp" />
<div
ref="desc"
class="markup-description"
v-html="pollStore.descriptionMarkUp" />

Check warning on line 16 in src/components/Poll/MarkUpDescription.vue

View workflow job for this annotation

GitHub Actions / NPM lint

'v-html' directive can lead to XSS attack
</template>

<style lang="scss">
.markup-description * {
margin: revert;
padding: revert;
font-size: revert;
text-decoration: revert;
list-style: revert;
opacity: revert;
min-height: revert;
.markup-description {
padding: 0.5rem;
margin: 0.25rem;
overflow: auto;

* {
margin: revert;
font-size: revert;
text-decoration: revert;
list-style: inside;
}
}

.markup-description {
Expand Down
8 changes: 0 additions & 8 deletions src/components/Settings/UserSettings/StyleSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,5 @@ const preferencesStore = usePreferencesStore()
{{ t('polls', 'Use alternative vote page styling') }}
</NcCheckboxRadioSwitch>
</div>
<div class="user_settings">
<NcCheckboxRadioSwitch
v-model="preferencesStore.user.useCardsArrangement"
type="switch"
@update:model-value="preferencesStore.write()">
{{ t('polls', 'Arrange description and card hints side by side') }}
</NcCheckboxRadioSwitch>
</div>
</div>
</template>
2 changes: 0 additions & 2 deletions src/stores/preferences.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ export type UserPreferences = {
useNewPollInPollist: boolean
useCommentsAlternativeStyling: boolean
useAlternativeStyling: boolean
useCardsArrangement: boolean
}

export type SessionSettings = {
Expand Down Expand Up @@ -65,7 +64,6 @@ export const usePreferencesStore = defineStore('preferences', {
useNewPollInPollist: false,
useCommentsAlternativeStyling: false,
useAlternativeStyling: false,
useCardsArrangement: false,
},
session: {
manualViewDatePoll: '',
Expand Down
39 changes: 18 additions & 21 deletions src/views/Vote.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import { usePollStore, PollType } from '../stores/poll.ts'
import { useOptionsStore } from '../stores/options.ts'
import { usePreferencesStore } from '../stores/preferences.ts'
import { Event } from '../Types/index.ts'
import Collapsible from '../components/Base/modules/Collapsible.vue'

const pollStore = usePollStore()
const optionsStore = useOptionsStore()
Expand Down Expand Up @@ -67,6 +68,16 @@ const windowTitle = computed(
() => `${t('polls', 'Polls')} - ${pollStore.configuration.title}`,
)

const isShortDescription = computed(() => {
if (!pollStore.configuration.description) {
return false
}
// If less than 20 words and less than 5 lines, then it's short
return (
pollStore.configuration.description.split(' ').length < 20
&& pollStore.configuration.description.split(/\r\n|\r|\n/).length < 5
)
})
onMounted(() => {
subscribe(Event.LoadPoll, () => pollStore.load())
emit(Event.TransitionsOff, 500)
Expand Down Expand Up @@ -102,29 +113,15 @@ onUnmounted(() => {
</HeaderBar>

<div class="vote_main">
<VoteInfoCards v-if="!preferencesStore.user.useCardsArrangement" />

<div
v-if="
pollStore.configuration.description
&& !preferencesStore.user.useCardsArrangement
"
class="area__description">
<Collapsible
v-if="pollStore.configuration.description"
:show-more-caption="pollStore.configuration.description"
:no-collapse="isShortDescription"
:initial-collapsed="!!pollStore.currentUserStatus.countVotes">
<MarkUpDescription />
</div>
</Collapsible>

<div v-if="preferencesStore.user.useCardsArrangement" class="top_area">
<div
v-if="pollStore.configuration.description"
class="description_container">
<div class="area__description">
<MarkUpDescription />
</div>
</div>
<div class="cards_container">
<VoteInfoCards />
</div>
</div>
<VoteInfoCards />

<VoteTable v-show="optionsStore.list.length" />

Expand Down