mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2026-03-01 12:44:37 +00:00
fix(webapp): add responsive mobile menu with locale switching and filter support (#9281)
This commit is contained in:
parent
30d88e9b41
commit
9548ad6e31
@ -3,23 +3,40 @@ import gql from 'graphql-tag'
|
|||||||
export const UpdateUser = gql`
|
export const UpdateUser = gql`
|
||||||
mutation (
|
mutation (
|
||||||
$id: ID!
|
$id: ID!
|
||||||
|
$slug: String
|
||||||
$name: String
|
$name: String
|
||||||
$termsAndConditionsAgreedVersion: String
|
$about: String
|
||||||
$locationName: String # empty string '' sets it to null
|
$allowEmbedIframes: Boolean
|
||||||
|
$showShoutsPublicly: Boolean
|
||||||
$emailNotificationSettings: [EmailNotificationSettingsInput]
|
$emailNotificationSettings: [EmailNotificationSettingsInput]
|
||||||
|
$termsAndConditionsAgreedVersion: String
|
||||||
|
$avatar: ImageInput
|
||||||
|
$locationName: String # empty string '' sets it to null
|
||||||
|
$locale: String
|
||||||
) {
|
) {
|
||||||
UpdateUser(
|
UpdateUser(
|
||||||
id: $id
|
id: $id
|
||||||
|
slug: $slug
|
||||||
name: $name
|
name: $name
|
||||||
termsAndConditionsAgreedVersion: $termsAndConditionsAgreedVersion
|
about: $about
|
||||||
locationName: $locationName
|
allowEmbedIframes: $allowEmbedIframes
|
||||||
|
showShoutsPublicly: $showShoutsPublicly
|
||||||
emailNotificationSettings: $emailNotificationSettings
|
emailNotificationSettings: $emailNotificationSettings
|
||||||
|
termsAndConditionsAgreedVersion: $termsAndConditionsAgreedVersion
|
||||||
|
avatar: $avatar
|
||||||
|
locationName: $locationName
|
||||||
|
locale: $locale
|
||||||
) {
|
) {
|
||||||
id
|
id
|
||||||
|
slug
|
||||||
name
|
name
|
||||||
|
about
|
||||||
|
allowEmbedIframes
|
||||||
|
showShoutsPublicly
|
||||||
termsAndConditionsAgreedVersion
|
termsAndConditionsAgreedVersion
|
||||||
termsAndConditionsAgreedAt
|
termsAndConditionsAgreedAt
|
||||||
locationName
|
locationName
|
||||||
|
locale
|
||||||
location {
|
location {
|
||||||
name
|
name
|
||||||
nameDE
|
nameDE
|
||||||
@ -33,6 +50,18 @@ export const UpdateUser = gql`
|
|||||||
value
|
value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
avatar {
|
||||||
|
url
|
||||||
|
alt
|
||||||
|
sensitive
|
||||||
|
aspectRatio
|
||||||
|
type
|
||||||
|
}
|
||||||
|
badgeVerification {
|
||||||
|
id
|
||||||
|
description
|
||||||
|
icon
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
import { defineStep } from '@badeball/cypress-cucumber-preprocessor'
|
import { defineStep } from '@badeball/cypress-cucumber-preprocessor'
|
||||||
|
|
||||||
defineStep('I select {string} in the language menu', language => {
|
defineStep('I select {string} in the language menu', language => {
|
||||||
cy.get('.locale-menu')
|
cy.get('.locale-menu:visible')
|
||||||
|
.first()
|
||||||
.click()
|
.click()
|
||||||
cy.contains('.locale-menu-popover a', language)
|
cy.contains('.locale-menu-popover a', language)
|
||||||
.click()
|
.click()
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
import { defineStep } from '@badeball/cypress-cucumber-preprocessor'
|
import { defineStep } from '@badeball/cypress-cucumber-preprocessor'
|
||||||
|
|
||||||
defineStep('open the notification menu and click on the first item', () => {
|
defineStep('open the notification menu and click on the first item', () => {
|
||||||
cy.get('.notifications-menu')
|
cy.get('.notifications-menu:visible')
|
||||||
|
.first()
|
||||||
.invoke('show')
|
.invoke('show')
|
||||||
.click() // 'invoke('show')' because of the delay for show the menu
|
.click() // 'invoke('show')' because of the delay for show the menu
|
||||||
cy.get('.notification-content a')
|
cy.get('.notification-content a')
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { defineStep } from '@badeball/cypress-cucumber-preprocessor'
|
import { defineStep } from '@badeball/cypress-cucumber-preprocessor'
|
||||||
|
|
||||||
defineStep('see {int} unread notifications in the top menu', count => {
|
defineStep('see {int} unread notifications in the top menu', count => {
|
||||||
cy.get('.notifications-menu')
|
cy.get('.notifications-menu:visible')
|
||||||
|
.first()
|
||||||
.should('contain', count)
|
.should('contain', count)
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
import { defineStep } from '@badeball/cypress-cucumber-preprocessor'
|
import { defineStep } from '@badeball/cypress-cucumber-preprocessor'
|
||||||
|
|
||||||
defineStep('the notification menu button links to the all notifications page', () => {
|
defineStep('the notification menu button links to the all notifications page', () => {
|
||||||
cy.get('.notifications-menu')
|
cy.get('.notifications-menu:visible')
|
||||||
|
.first()
|
||||||
.click()
|
.click()
|
||||||
cy.location('pathname')
|
cy.location('pathname')
|
||||||
.should('contain', '/notifications')
|
.should('contain', '/notifications')
|
||||||
|
|||||||
5
packages/ui/src/ocelot/icons/svgs/language.svg
Normal file
5
packages/ui/src/ocelot/icons/svgs/language.svg
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<!-- Font Awesome Free 6.7.2 "language" icon (CC BY 4.0) -->
|
||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 640 512">
|
||||||
|
<title>language</title>
|
||||||
|
<path d="M0 128C0 92.7 28.7 64 64 64l192 0 48 0 16 0 256 0c35.3 0 64 28.7 64 64l0 256c0 35.3-28.7 64-64 64l-256 0-16 0-48 0L64 448c-35.3 0-64-28.7-64-64L0 128zm320 0l0 256 256 0 0-256-256 0zM178.3 175.9c-3.2-7.2-10.4-11.9-18.3-11.9s-15.1 4.7-18.3 11.9l-64 144c-4.5 10.1 .1 21.9 10.2 26.4s21.9-.1 26.4-10.2l8.9-20.1 73.6 0 8.9 20.1c4.5 10.1 16.3 14.6 26.4 10.2s14.6-16.3 10.2-26.4l-64-144zM160 233.2L179 276l-38 0 19-42.8zM448 164c11 0 20 9 20 20l0 4 44 0 16 0c11 0 20 9 20 20s-9 20-20 20l-2 0-1.6 4.5c-8.9 24.4-22.4 46.6-39.6 65.4c.9 .6 1.8 1.1 2.7 1.6l18.9 11.3c9.5 5.7 12.5 18 6.9 27.4s-18 12.5-27.4 6.9l-18.9-11.3c-4.5-2.7-8.8-5.5-13.1-8.5c-10.6 7.5-21.9 14-34 19.4l-3.6 1.6c-10.1 4.5-21.9-.1-26.4-10.2s.1-21.9 10.2-26.4l3.6-1.6c6.4-2.9 12.6-6.1 18.5-9.8l-12.2-12.2c-7.8-7.8-7.8-20.5 0-28.3s20.5-7.8 28.3 0l14.6 14.6 .5 .5c12.4-13.1 22.5-28.3 29.8-45L448 228l-72 0c-11 0-20-9-20-20s9-20 20-20l52 0 0-4c0-11 9-20 20-20z"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
@ -359,6 +359,7 @@ $media-query-small: "(min-width: 600px)";
|
|||||||
$media-query-medium: "(min-width: 768px)";
|
$media-query-medium: "(min-width: 768px)";
|
||||||
$media-query-large: "(min-width: 1024px)";
|
$media-query-large: "(min-width: 1024px)";
|
||||||
$media-query-x-large: "(min-width: 1200px)";
|
$media-query-x-large: "(min-width: 1200px)";
|
||||||
|
$container-max-width-x-large: 1200px;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @tokens Background Images
|
* @tokens Background Images
|
||||||
|
|||||||
@ -1,26 +1,28 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="donation-info">
|
<page-params-link :pageParams="links.DONATE" class="donation-info">
|
||||||
<progress-bar :label="label" :goal="goal" :progress="progress">
|
<progress-bar :label="label" :goal="goal" :progress="progress">
|
||||||
<os-button size="sm" variant="primary" @click="redirectToPage(links.DONATE)">
|
<os-button size="sm" variant="primary">
|
||||||
{{ $t('donations.donate-now') }}
|
{{ $t('donations.donate-now') }}
|
||||||
<template #suffix>
|
<template #suffix>
|
||||||
<os-icon :icon="icons.heartO" />
|
<os-icon :icon="icons.heartO" />
|
||||||
</template>
|
</template>
|
||||||
</os-button>
|
</os-button>
|
||||||
</progress-bar>
|
</progress-bar>
|
||||||
</div>
|
</page-params-link>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { OsButton, OsIcon } from '@ocelot-social/ui'
|
import { OsButton, OsIcon } from '@ocelot-social/ui'
|
||||||
import { iconRegistry } from '~/utils/iconRegistry'
|
import { iconRegistry } from '~/utils/iconRegistry'
|
||||||
import links from '~/constants/links.js'
|
import links from '~/constants/links.js'
|
||||||
|
import PageParamsLink from '~/components/_new/features/PageParamsLink/PageParamsLink.vue'
|
||||||
import ProgressBar from '~/components/ProgressBar/ProgressBar.vue'
|
import ProgressBar from '~/components/ProgressBar/ProgressBar.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
OsButton,
|
OsButton,
|
||||||
OsIcon,
|
OsIcon,
|
||||||
|
PageParamsLink,
|
||||||
ProgressBar,
|
ProgressBar,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
@ -44,11 +46,6 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
|
||||||
redirectToPage(pageParams) {
|
|
||||||
pageParams.redirectToPage(this)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -58,5 +55,6 @@ export default {
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
margin-bottom: $space-x-small;
|
margin-bottom: $space-x-small;
|
||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,16 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<dropdown ref="menu" placement="top-start" :offset="8" class="filter-menu">
|
<dropdown ref="menu" :placement="placement" :offset="offset" class="filter-menu">
|
||||||
<template #default="{ toggleMenu }">
|
<template #default="{ toggleMenu }">
|
||||||
<os-button
|
<os-button
|
||||||
variant="primary"
|
variant="primary"
|
||||||
:appearance="filterActive ? 'filled' : 'ghost'"
|
:appearance="filterActive ? 'filled' : 'ghost'"
|
||||||
|
circle
|
||||||
:aria-label="$t('common.filter')"
|
:aria-label="$t('common.filter')"
|
||||||
@click.prevent="toggleMenu()"
|
@click.prevent="toggleMenu()"
|
||||||
>
|
>
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<os-icon :icon="icons.filter" />
|
<os-icon :icon="icons.filter" />
|
||||||
</template>
|
</template>
|
||||||
<os-icon class="dropdown-arrow" :icon="icons.angleDown" />
|
|
||||||
</os-button>
|
</os-button>
|
||||||
</template>
|
</template>
|
||||||
<template #popover>
|
<template #popover>
|
||||||
@ -34,8 +34,8 @@ export default {
|
|||||||
OsIcon,
|
OsIcon,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
placement: { type: String },
|
placement: { type: String, default: 'top-start' },
|
||||||
offset: { type: [String, Number] },
|
offset: { type: [String, Number], default: 8 },
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters({
|
...mapGetters({
|
||||||
|
|||||||
@ -61,6 +61,7 @@ export default {
|
|||||||
|
|
||||||
> .filter-list {
|
> .filter-list {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
flex-basis: 100%;
|
flex-basis: 100%;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
padding-left: $space-base;
|
padding-left: $space-base;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -6,11 +6,11 @@ import Vuex from 'vuex'
|
|||||||
const localVue = global.localVue
|
const localVue = global.localVue
|
||||||
|
|
||||||
const stubs = {
|
const stubs = {
|
||||||
'client-only': true,
|
'client-only': { template: '<div><slot /></div>' },
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('LocaleSwitch.vue', () => {
|
describe('LocaleSwitch.vue', () => {
|
||||||
let wrapper, mocks, computed, deutschLanguageItem, getters
|
let wrapper, mocks, computed, getters
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mocks = {
|
mocks = {
|
||||||
@ -48,10 +48,12 @@ describe('LocaleSwitch.vue', () => {
|
|||||||
{
|
{
|
||||||
name: 'English',
|
name: 'English',
|
||||||
path: 'en',
|
path: 'en',
|
||||||
|
flag: '🇬🇧',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Deutsch',
|
name: 'Deutsch',
|
||||||
path: 'de',
|
path: 'de',
|
||||||
|
flag: '🇩🇪',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -71,37 +73,61 @@ describe('LocaleSwitch.vue', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
describe('with current user', () => {
|
describe('with current user', () => {
|
||||||
beforeEach(() => {
|
let toggleMenu
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
toggleMenu = jest.fn()
|
||||||
wrapper = Wrapper()
|
wrapper = Wrapper()
|
||||||
wrapper.find('.locale-menu').trigger('click')
|
await wrapper.vm.changeLanguage('de', toggleMenu)
|
||||||
deutschLanguageItem = wrapper.findAll('li').at(1)
|
|
||||||
deutschLanguageItem.trigger('click')
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it("sets a user's locale", () => {
|
it("sets a user's locale", () => {
|
||||||
expect(mocks.$i18n.set).toHaveBeenCalledTimes(1)
|
expect(mocks.$i18n.set).toHaveBeenCalledWith('de')
|
||||||
})
|
})
|
||||||
|
|
||||||
it("updates the user's locale in the database", () => {
|
it("updates the user's locale in the database", () => {
|
||||||
expect(mocks.$apollo.mutate).toHaveBeenCalledTimes(1)
|
expect(mocks.$apollo.mutate).toHaveBeenCalledTimes(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('closes the menu', () => {
|
||||||
|
expect(toggleMenu).toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('when apollo mutation fails', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
wrapper = Wrapper()
|
||||||
|
// First call succeeds (consumes mockResolvedValueOnce)
|
||||||
|
await wrapper.vm.changeLanguage('de', jest.fn())
|
||||||
|
// Second call fails (consumes mockRejectedValueOnce)
|
||||||
|
await wrapper.vm.changeLanguage('en', jest.fn())
|
||||||
|
})
|
||||||
|
|
||||||
|
it('shows an error toast', () => {
|
||||||
|
expect(mocks.$toast.error).toHaveBeenCalledWith('Please log in!')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('no current user', () => {
|
describe('no current user', () => {
|
||||||
beforeEach(() => {
|
let toggleMenu
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
toggleMenu = jest.fn()
|
||||||
getters = {
|
getters = {
|
||||||
'auth/user': () => {
|
'auth/user': () => {
|
||||||
return null
|
return null
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
wrapper = Wrapper()
|
wrapper = Wrapper()
|
||||||
wrapper.find('.locale-menu').trigger('click')
|
await wrapper.vm.changeLanguage('de', toggleMenu)
|
||||||
deutschLanguageItem = wrapper.findAll('li').at(1)
|
|
||||||
deutschLanguageItem.trigger('click')
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('does not send a UpdateUser mutation', () => {
|
it('does not send a UpdateUser mutation', () => {
|
||||||
expect(mocks.$apollo.mutate).not.toHaveBeenCalled()
|
expect(mocks.$apollo.mutate).not.toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('still closes the menu', () => {
|
||||||
|
expect(toggleMenu).toHaveBeenCalled()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -2,18 +2,22 @@
|
|||||||
<client-only>
|
<client-only>
|
||||||
<dropdown ref="menu" :placement="placement" :offset="offset">
|
<dropdown ref="menu" :placement="placement" :offset="offset">
|
||||||
<template #default="{ toggleMenu }">
|
<template #default="{ toggleMenu }">
|
||||||
<a
|
<os-button
|
||||||
class="locale-menu"
|
class="locale-menu"
|
||||||
href="#"
|
variant="primary"
|
||||||
|
appearance="ghost"
|
||||||
|
circle
|
||||||
|
:aria-label="$t('localeSwitch.tooltip')"
|
||||||
v-tooltip="{
|
v-tooltip="{
|
||||||
content: $t('localeSwitch.tooltip'),
|
content: $t('localeSwitch.tooltip'),
|
||||||
placement: 'bottom-start',
|
placement: 'bottom-start',
|
||||||
}"
|
}"
|
||||||
@click.prevent="toggleMenu()"
|
@click.prevent="toggleMenu()"
|
||||||
>
|
>
|
||||||
<span class="label">{{ current.code.toUpperCase() }}</span>
|
<template #icon>
|
||||||
<os-icon class="dropdown-arrow" :icon="icons.angleDown" />
|
<os-icon :icon="icons.language" />
|
||||||
</a>
|
</template>
|
||||||
|
</os-button>
|
||||||
</template>
|
</template>
|
||||||
<template #popover="{ toggleMenu }">
|
<template #popover="{ toggleMenu }">
|
||||||
<ds-menu class="locale-menu-popover" :matcher="matcher" :routes="routes">
|
<ds-menu class="locale-menu-popover" :matcher="matcher" :routes="routes">
|
||||||
@ -24,6 +28,7 @@
|
|||||||
:parents="item.parents"
|
:parents="item.parents"
|
||||||
@click.stop.prevent="changeLanguage(item.route.path, toggleMenu)"
|
@click.stop.prevent="changeLanguage(item.route.path, toggleMenu)"
|
||||||
>
|
>
|
||||||
|
<span class="locale-flag">{{ item.route.flag }}</span>
|
||||||
{{ item.route.name }}
|
{{ item.route.name }}
|
||||||
</ds-menu-item>
|
</ds-menu-item>
|
||||||
</template>
|
</template>
|
||||||
@ -34,18 +39,19 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { OsIcon } from '@ocelot-social/ui'
|
import { OsButton, OsIcon } from '@ocelot-social/ui'
|
||||||
import { iconRegistry } from '~/utils/iconRegistry'
|
import { iconRegistry } from '~/utils/iconRegistry'
|
||||||
import gql from 'graphql-tag'
|
|
||||||
import Dropdown from '~/components/Dropdown'
|
import Dropdown from '~/components/Dropdown'
|
||||||
import find from 'lodash/find'
|
import find from 'lodash/find'
|
||||||
import orderBy from 'lodash/orderBy'
|
import orderBy from 'lodash/orderBy'
|
||||||
import locales from '~/locales'
|
import locales from '~/locales'
|
||||||
import { mapGetters, mapMutations } from 'vuex'
|
import localeUpdate from '~/mixins/localeUpdate.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
mixins: [localeUpdate],
|
||||||
components: {
|
components: {
|
||||||
Dropdown,
|
Dropdown,
|
||||||
|
OsButton,
|
||||||
OsIcon,
|
OsIcon,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
@ -62,17 +68,12 @@ export default {
|
|||||||
return find(this.locales, { code: this.$i18n.locale() })
|
return find(this.locales, { code: this.$i18n.locale() })
|
||||||
},
|
},
|
||||||
routes() {
|
routes() {
|
||||||
const routes = this.locales.map((locale) => {
|
return this.locales.map((locale) => ({
|
||||||
return {
|
name: locale.name,
|
||||||
name: locale.name,
|
path: locale.code,
|
||||||
path: locale.code,
|
flag: locale.flag,
|
||||||
}
|
}))
|
||||||
})
|
|
||||||
return routes
|
|
||||||
},
|
},
|
||||||
...mapGetters({
|
|
||||||
currentUser: 'auth/user',
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.icons = iconRegistry
|
this.icons = iconRegistry
|
||||||
@ -86,57 +87,11 @@ export default {
|
|||||||
matcher(locale) {
|
matcher(locale) {
|
||||||
return locale === this.$i18n.locale()
|
return locale === this.$i18n.locale()
|
||||||
},
|
},
|
||||||
|
|
||||||
...mapMutations({
|
|
||||||
setCurrentUser: 'auth/SET_USER',
|
|
||||||
}),
|
|
||||||
async updateUserLocale() {
|
|
||||||
if (!this.currentUser || !this.currentUser.id) return null
|
|
||||||
try {
|
|
||||||
await this.$apollo.mutate({
|
|
||||||
mutation: gql`
|
|
||||||
mutation ($id: ID!, $locale: String) {
|
|
||||||
UpdateUser(id: $id, locale: $locale) {
|
|
||||||
id
|
|
||||||
locale
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
variables: {
|
|
||||||
id: this.currentUser.id,
|
|
||||||
locale: this.$i18n.locale(),
|
|
||||||
},
|
|
||||||
update: (store, { data: { UpdateUser } }) => {
|
|
||||||
const { locale } = UpdateUser
|
|
||||||
this.setCurrentUser({
|
|
||||||
...this.currentUser,
|
|
||||||
locale,
|
|
||||||
})
|
|
||||||
},
|
|
||||||
})
|
|
||||||
this.$toast.success(this.$t('contribution.success'))
|
|
||||||
} catch (err) {
|
|
||||||
this.$toast.error(err.message)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.locale-menu {
|
|
||||||
user-select: none;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
height: 100%;
|
|
||||||
padding: $space-xx-small;
|
|
||||||
color: $color-locale-menu;
|
|
||||||
|
|
||||||
> .label {
|
|
||||||
margin: 0 $space-xx-small;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nav.locale-menu-popover {
|
nav.locale-menu-popover {
|
||||||
margin-left: -$space-small !important;
|
margin-left: -$space-small !important;
|
||||||
margin-right: -$space-small !important;
|
margin-right: -$space-small !important;
|
||||||
@ -146,4 +101,10 @@ nav.locale-menu-popover {
|
|||||||
padding-right: $space-base;
|
padding-right: $space-base;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.locale-flag {
|
||||||
|
margin-right: $space-xx-small;
|
||||||
|
font-size: 1.2em;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -118,5 +118,9 @@ export default {
|
|||||||
.progress-bar-button {
|
.progress-bar-button {
|
||||||
position: relative;
|
position: relative;
|
||||||
float: right;
|
float: right;
|
||||||
|
|
||||||
|
@media (max-width: 810px) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -358,6 +358,7 @@ export const updateUserMutation = () => {
|
|||||||
$termsAndConditionsAgreedVersion: String
|
$termsAndConditionsAgreedVersion: String
|
||||||
$avatar: ImageInput
|
$avatar: ImageInput
|
||||||
$locationName: String # empty string '' sets it to null
|
$locationName: String # empty string '' sets it to null
|
||||||
|
$locale: String
|
||||||
) {
|
) {
|
||||||
UpdateUser(
|
UpdateUser(
|
||||||
id: $id
|
id: $id
|
||||||
@ -370,6 +371,7 @@ export const updateUserMutation = () => {
|
|||||||
termsAndConditionsAgreedVersion: $termsAndConditionsAgreedVersion
|
termsAndConditionsAgreedVersion: $termsAndConditionsAgreedVersion
|
||||||
avatar: $avatar
|
avatar: $avatar
|
||||||
locationName: $locationName
|
locationName: $locationName
|
||||||
|
locale: $locale
|
||||||
) {
|
) {
|
||||||
id
|
id
|
||||||
slug
|
slug
|
||||||
|
|||||||
@ -1,14 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="layout-default">
|
<div class="layout-default">
|
||||||
<div class="main-navigation">
|
<div class="main-navigation">
|
||||||
<header-menu :showMobileMenu="isMobile" />
|
<header-menu />
|
||||||
</div>
|
</div>
|
||||||
<div class="ds-container ds-container-x-large">
|
<div class="ds-container ds-container-x-large">
|
||||||
<div class="main-container">
|
<div class="main-container">
|
||||||
<nuxt />
|
<nuxt />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<page-footer v-if="!isMobile" />
|
<page-footer class="desktop-footer" />
|
||||||
<div id="overlay" />
|
<div id="overlay" />
|
||||||
<client-only>
|
<client-only>
|
||||||
<modal />
|
<modal />
|
||||||
@ -66,6 +66,12 @@ export default {
|
|||||||
padding-bottom: 8rem;
|
padding-bottom: 8rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.desktop-footer {
|
||||||
|
@media (max-width: 810px) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.chat-modul {
|
.chat-modul {
|
||||||
background-color: rgb(233, 228, 228);
|
background-color: rgb(233, 228, 228);
|
||||||
width: 355px;
|
width: 355px;
|
||||||
|
|||||||
@ -661,6 +661,7 @@
|
|||||||
"map": {
|
"map": {
|
||||||
"tooltip": "Landkarte"
|
"tooltip": "Landkarte"
|
||||||
},
|
},
|
||||||
|
"more": "Mehr",
|
||||||
"notifications": {
|
"notifications": {
|
||||||
"tooltip": "Benachrichtigungen"
|
"tooltip": "Benachrichtigungen"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -661,6 +661,7 @@
|
|||||||
"map": {
|
"map": {
|
||||||
"tooltip": "Map"
|
"tooltip": "Map"
|
||||||
},
|
},
|
||||||
|
"more": "More",
|
||||||
"notifications": {
|
"notifications": {
|
||||||
"tooltip": "Notifications"
|
"tooltip": "Notifications"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -661,6 +661,7 @@
|
|||||||
"map": {
|
"map": {
|
||||||
"tooltip": "Mapa"
|
"tooltip": "Mapa"
|
||||||
},
|
},
|
||||||
|
"more": "Más",
|
||||||
"notifications": {
|
"notifications": {
|
||||||
"tooltip": "Notificaciones"
|
"tooltip": "Notificaciones"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -661,6 +661,7 @@
|
|||||||
"map": {
|
"map": {
|
||||||
"tooltip": "Carte"
|
"tooltip": "Carte"
|
||||||
},
|
},
|
||||||
|
"more": "Plus",
|
||||||
"notifications": {
|
"notifications": {
|
||||||
"tooltip": "Notifications"
|
"tooltip": "Notifications"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@ const locales = [
|
|||||||
name: 'English',
|
name: 'English',
|
||||||
code: 'en',
|
code: 'en',
|
||||||
iso: 'en-US',
|
iso: 'en-US',
|
||||||
|
flag: '🇬🇧',
|
||||||
enabled: true,
|
enabled: true,
|
||||||
dateFnsLocale: enUS,
|
dateFnsLocale: enUS,
|
||||||
},
|
},
|
||||||
@ -13,6 +14,7 @@ const locales = [
|
|||||||
name: 'Deutsch',
|
name: 'Deutsch',
|
||||||
code: 'de',
|
code: 'de',
|
||||||
iso: 'de-DE',
|
iso: 'de-DE',
|
||||||
|
flag: '🇩🇪',
|
||||||
enabled: true,
|
enabled: true,
|
||||||
dateFnsLocale: de,
|
dateFnsLocale: de,
|
||||||
},
|
},
|
||||||
@ -20,6 +22,7 @@ const locales = [
|
|||||||
name: 'Nederlands',
|
name: 'Nederlands',
|
||||||
code: 'nl',
|
code: 'nl',
|
||||||
iso: 'nl-NL',
|
iso: 'nl-NL',
|
||||||
|
flag: '🇳🇱',
|
||||||
enabled: true,
|
enabled: true,
|
||||||
dateFnsLocale: nl,
|
dateFnsLocale: nl,
|
||||||
},
|
},
|
||||||
@ -27,6 +30,7 @@ const locales = [
|
|||||||
name: 'Français',
|
name: 'Français',
|
||||||
code: 'fr',
|
code: 'fr',
|
||||||
iso: 'fr-FR',
|
iso: 'fr-FR',
|
||||||
|
flag: '🇫🇷',
|
||||||
enabled: true,
|
enabled: true,
|
||||||
dateFnsLocale: fr,
|
dateFnsLocale: fr,
|
||||||
},
|
},
|
||||||
@ -34,6 +38,7 @@ const locales = [
|
|||||||
name: 'Italiano',
|
name: 'Italiano',
|
||||||
code: 'it',
|
code: 'it',
|
||||||
iso: 'it-IT',
|
iso: 'it-IT',
|
||||||
|
flag: '🇮🇹',
|
||||||
enabled: true,
|
enabled: true,
|
||||||
dateFnsLocale: it,
|
dateFnsLocale: it,
|
||||||
},
|
},
|
||||||
@ -41,6 +46,7 @@ const locales = [
|
|||||||
name: 'Español',
|
name: 'Español',
|
||||||
code: 'es',
|
code: 'es',
|
||||||
iso: 'es-ES',
|
iso: 'es-ES',
|
||||||
|
flag: '🇪🇸',
|
||||||
enabled: true,
|
enabled: true,
|
||||||
dateFnsLocale: es,
|
dateFnsLocale: es,
|
||||||
},
|
},
|
||||||
@ -48,6 +54,7 @@ const locales = [
|
|||||||
name: 'Português',
|
name: 'Português',
|
||||||
code: 'pt',
|
code: 'pt',
|
||||||
iso: 'pt-PT',
|
iso: 'pt-PT',
|
||||||
|
flag: '🇵🇹',
|
||||||
enabled: true,
|
enabled: true,
|
||||||
dateFnsLocale: pt,
|
dateFnsLocale: pt,
|
||||||
},
|
},
|
||||||
@ -55,6 +62,7 @@ const locales = [
|
|||||||
name: 'Polski',
|
name: 'Polski',
|
||||||
code: 'pl',
|
code: 'pl',
|
||||||
iso: 'pl-PL',
|
iso: 'pl-PL',
|
||||||
|
flag: '🇵🇱',
|
||||||
enabled: true,
|
enabled: true,
|
||||||
dateFnsLocale: pl,
|
dateFnsLocale: pl,
|
||||||
},
|
},
|
||||||
@ -62,6 +70,7 @@ const locales = [
|
|||||||
name: 'Русский',
|
name: 'Русский',
|
||||||
code: 'ru',
|
code: 'ru',
|
||||||
iso: 'ru-RU',
|
iso: 'ru-RU',
|
||||||
|
flag: '🇷🇺',
|
||||||
enabled: true,
|
enabled: true,
|
||||||
dateFnsLocale: ru,
|
dateFnsLocale: ru,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -661,6 +661,7 @@
|
|||||||
"map": {
|
"map": {
|
||||||
"tooltip": null
|
"tooltip": null
|
||||||
},
|
},
|
||||||
|
"more": "Altro",
|
||||||
"notifications": {
|
"notifications": {
|
||||||
"tooltip": "Notifiche"
|
"tooltip": "Notifiche"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -661,6 +661,7 @@
|
|||||||
"map": {
|
"map": {
|
||||||
"tooltip": null
|
"tooltip": null
|
||||||
},
|
},
|
||||||
|
"more": "Meer",
|
||||||
"notifications": {
|
"notifications": {
|
||||||
"tooltip": "Notificaties"
|
"tooltip": "Notificaties"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -661,6 +661,7 @@
|
|||||||
"map": {
|
"map": {
|
||||||
"tooltip": null
|
"tooltip": null
|
||||||
},
|
},
|
||||||
|
"more": "Więcej",
|
||||||
"notifications": {
|
"notifications": {
|
||||||
"tooltip": "Powiadomienia"
|
"tooltip": "Powiadomienia"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -661,6 +661,7 @@
|
|||||||
"map": {
|
"map": {
|
||||||
"tooltip": null
|
"tooltip": null
|
||||||
},
|
},
|
||||||
|
"more": "Mais",
|
||||||
"notifications": {
|
"notifications": {
|
||||||
"tooltip": "Notificações"
|
"tooltip": "Notificações"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -661,6 +661,7 @@
|
|||||||
"map": {
|
"map": {
|
||||||
"tooltip": null
|
"tooltip": null
|
||||||
},
|
},
|
||||||
|
"more": "Ещё",
|
||||||
"notifications": {
|
"notifications": {
|
||||||
"tooltip": "Уведомления"
|
"tooltip": "Уведомления"
|
||||||
}
|
}
|
||||||
|
|||||||
36
webapp/mixins/localeUpdate.js
Normal file
36
webapp/mixins/localeUpdate.js
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import { mapGetters, mapMutations } from 'vuex'
|
||||||
|
import { updateUserMutation } from '~/graphql/User.js'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
computed: {
|
||||||
|
...mapGetters({
|
||||||
|
currentUser: 'auth/user',
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapMutations({
|
||||||
|
setCurrentUser: 'auth/SET_USER',
|
||||||
|
}),
|
||||||
|
async updateUserLocale() {
|
||||||
|
if (!this.currentUser || !this.currentUser.id) return
|
||||||
|
try {
|
||||||
|
await this.$apollo.mutate({
|
||||||
|
mutation: updateUserMutation(),
|
||||||
|
variables: {
|
||||||
|
id: this.currentUser.id,
|
||||||
|
locale: this.$i18n.locale(),
|
||||||
|
},
|
||||||
|
update: (_store, { data: { UpdateUser } }) => {
|
||||||
|
this.setCurrentUser({
|
||||||
|
...this.currentUser,
|
||||||
|
locale: UpdateUser.locale,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
this.$toast.success(this.$t('contribution.success'))
|
||||||
|
} catch (err) {
|
||||||
|
this.$toast.error(err.message)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
@ -1,7 +1,71 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<!-- create post -->
|
<!-- feed top row: filter (left) + create post (right) -->
|
||||||
<div :class="POST_ADD_BUTTON_POSITION_TOP ? 'box-add-button-top' : ''">
|
<div class="feed-top-row">
|
||||||
|
<div v-if="SHOW_CONTENT_FILTER_MASONRY_GRID" class="filterButtonMenu">
|
||||||
|
<os-button
|
||||||
|
class="my-filter-button"
|
||||||
|
v-if="
|
||||||
|
!postsFilter['postType_in'] &&
|
||||||
|
!postsFilter['categories_some'] &&
|
||||||
|
!postsFilter['author'] &&
|
||||||
|
!postsFilter['postsInMyGroups']
|
||||||
|
"
|
||||||
|
variant="primary"
|
||||||
|
appearance="filled"
|
||||||
|
@click="showFilter = !showFilter"
|
||||||
|
>
|
||||||
|
<template #suffix>
|
||||||
|
<os-icon :icon="filterButtonIcon" />
|
||||||
|
</template>
|
||||||
|
{{ $t('contribution.filterMasonryGrid.noFilter') }}
|
||||||
|
</os-button>
|
||||||
|
|
||||||
|
<header-button
|
||||||
|
v-if="filteredPostTypes.includes('Article')"
|
||||||
|
:title="$t('contribution.filterMasonryGrid.onlyArticles')"
|
||||||
|
:clickButton="openFilterMenu"
|
||||||
|
:titleRemove="$t('filter-menu.deleteFilter')"
|
||||||
|
:clickRemove="resetPostType"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<header-button
|
||||||
|
v-if="filteredPostTypes.includes('Event')"
|
||||||
|
:title="$t('contribution.filterMasonryGrid.onlyEvents')"
|
||||||
|
:clickButton="openFilterMenu"
|
||||||
|
:titleRemove="$t('filter-menu.deleteFilter')"
|
||||||
|
:clickRemove="resetPostType"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<header-button
|
||||||
|
v-if="postsFilter['categories_some']"
|
||||||
|
:title="$t('contribution.filterMasonryGrid.myTopics')"
|
||||||
|
:clickButton="openFilterMenu"
|
||||||
|
:titleRemove="$t('filter-menu.deleteFilter')"
|
||||||
|
:clickRemove="resetCategories"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<header-button
|
||||||
|
v-if="postsFilter['author']"
|
||||||
|
:title="$t('contribution.filterMasonryGrid.myFriends')"
|
||||||
|
:clickButton="openFilterMenu"
|
||||||
|
:titleRemove="$t('filter-menu.deleteFilter')"
|
||||||
|
:clickRemove="resetByFollowed"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<header-button
|
||||||
|
v-if="postsFilter['postsInMyGroups']"
|
||||||
|
:title="$t('contribution.filterMasonryGrid.myGroups')"
|
||||||
|
:clickButton="openFilterMenu"
|
||||||
|
:titleRemove="$t('filter-menu.deleteFilter')"
|
||||||
|
:clickRemove="resetByGroups"
|
||||||
|
/>
|
||||||
|
<div id="my-filter" v-if="showFilter">
|
||||||
|
<div @mouseleave="mouseLeaveFilterMenu">
|
||||||
|
<filter-menu-component @showFilterMenu="showFilterMenu" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<client-only>
|
<client-only>
|
||||||
<os-button
|
<os-button
|
||||||
as="nuxt-link"
|
as="nuxt-link"
|
||||||
@ -11,10 +75,7 @@
|
|||||||
placement: 'left',
|
placement: 'left',
|
||||||
}"
|
}"
|
||||||
class="post-add-button"
|
class="post-add-button"
|
||||||
:class="[
|
:class="{ 'hide-filter': hideByScroll }"
|
||||||
POST_ADD_BUTTON_POSITION_TOP ? 'post-add-button-top' : 'post-add-button-bottom',
|
|
||||||
{ 'hide-filter': hideByScroll },
|
|
||||||
]"
|
|
||||||
variant="primary"
|
variant="primary"
|
||||||
appearance="filled"
|
appearance="filled"
|
||||||
circle
|
circle
|
||||||
@ -26,78 +87,12 @@
|
|||||||
</os-button>
|
</os-button>
|
||||||
</client-only>
|
</client-only>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
|
||||||
<div v-if="SHOW_CONTENT_FILTER_MASONRY_GRID" class="top-filter-menu">
|
|
||||||
<div class="filterButtonBox">
|
|
||||||
<div class="filterButtonMenu" :class="{ 'hide-filter': hideByScroll }">
|
|
||||||
<os-button
|
|
||||||
class="my-filter-button"
|
|
||||||
v-if="
|
|
||||||
!postsFilter['postType_in'] &&
|
|
||||||
!postsFilter['categories_some'] &&
|
|
||||||
!postsFilter['author'] &&
|
|
||||||
!postsFilter['postsInMyGroups']
|
|
||||||
"
|
|
||||||
variant="primary"
|
|
||||||
appearance="filled"
|
|
||||||
@click="showFilter = !showFilter"
|
|
||||||
>
|
|
||||||
<template #suffix>
|
|
||||||
<os-icon :icon="filterButtonIcon" />
|
|
||||||
</template>
|
|
||||||
{{ $t('contribution.filterMasonryGrid.noFilter') }}
|
|
||||||
</os-button>
|
|
||||||
|
|
||||||
<header-button
|
<div
|
||||||
v-if="filteredPostTypes.includes('Article')"
|
v-if="hashtag || showDonations"
|
||||||
:title="$t('contribution.filterMasonryGrid.onlyArticles')"
|
class="newsfeed-controls"
|
||||||
:clickButton="openFilterMenu"
|
:class="{ 'newsfeed-controls--no-filter': !SHOW_CONTENT_FILTER_MASONRY_GRID }"
|
||||||
:titleRemove="$t('filter-menu.deleteFilter')"
|
>
|
||||||
:clickRemove="resetPostType"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<header-button
|
|
||||||
v-if="filteredPostTypes.includes('Event')"
|
|
||||||
:title="$t('contribution.filterMasonryGrid.onlyEvents')"
|
|
||||||
:clickButton="openFilterMenu"
|
|
||||||
:titleRemove="$t('filter-menu.deleteFilter')"
|
|
||||||
:clickRemove="resetPostType"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<header-button
|
|
||||||
v-if="postsFilter['categories_some']"
|
|
||||||
:title="$t('contribution.filterMasonryGrid.myTopics')"
|
|
||||||
:clickButton="openFilterMenu"
|
|
||||||
:titleRemove="$t('filter-menu.deleteFilter')"
|
|
||||||
:clickRemove="resetCategories"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<header-button
|
|
||||||
v-if="postsFilter['author']"
|
|
||||||
:title="$t('contribution.filterMasonryGrid.myFriends')"
|
|
||||||
:clickButton="openFilterMenu"
|
|
||||||
:titleRemove="$t('filter-menu.deleteFilter')"
|
|
||||||
:clickRemove="resetByFollowed"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<header-button
|
|
||||||
v-if="postsFilter['postsInMyGroups']"
|
|
||||||
:title="$t('contribution.filterMasonryGrid.myGroups')"
|
|
||||||
:clickButton="openFilterMenu"
|
|
||||||
:titleRemove="$t('filter-menu.deleteFilter')"
|
|
||||||
:clickRemove="resetByGroups"
|
|
||||||
/>
|
|
||||||
<div id="my-filter" v-if="showFilter">
|
|
||||||
<div @mouseleave="mouseLeaveFilterMenu">
|
|
||||||
<filter-menu-component @showFilterMenu="showFilterMenu" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div v-if="hashtag || showDonations" class="newsfeed-controls">
|
|
||||||
<div v-if="hashtag">
|
<div v-if="hashtag">
|
||||||
<hashtags-filter :hashtag="hashtag" @clearSearch="clearSearch" />
|
<hashtags-filter :hashtag="hashtag" @clearSearch="clearSearch" />
|
||||||
</div>
|
</div>
|
||||||
@ -171,7 +166,6 @@ import { filterPosts } from '~/graphql/PostQuery.js'
|
|||||||
import UpdateQuery from '~/components/utils/UpdateQuery'
|
import UpdateQuery from '~/components/utils/UpdateQuery'
|
||||||
import FilterMenuComponent from '~/components/FilterMenu/FilterMenuComponent'
|
import FilterMenuComponent from '~/components/FilterMenu/FilterMenuComponent'
|
||||||
import { SHOW_CONTENT_FILTER_MASONRY_GRID } from '~/constants/filter.js'
|
import { SHOW_CONTENT_FILTER_MASONRY_GRID } from '~/constants/filter.js'
|
||||||
import { POST_ADD_BUTTON_POSITION_TOP } from '~/constants/posts.js'
|
|
||||||
import GetCategories from '~/mixins/getCategoriesMixin.js'
|
import GetCategories from '~/mixins/getCategoriesMixin.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -206,7 +200,6 @@ export default {
|
|||||||
pageSize: 12,
|
pageSize: 12,
|
||||||
hashtag,
|
hashtag,
|
||||||
SHOW_CONTENT_FILTER_MASONRY_GRID,
|
SHOW_CONTENT_FILTER_MASONRY_GRID,
|
||||||
POST_ADD_BUTTON_POSITION_TOP,
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -364,65 +357,59 @@ export default {
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.box-add-button-top {
|
.feed-top-row {
|
||||||
float: right;
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 16px;
|
||||||
|
margin-top: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.post-add-button-bottom {
|
.filterButtonMenu {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-add-button {
|
||||||
height: 54px !important;
|
height: 54px !important;
|
||||||
width: 54px !important;
|
width: 54px !important;
|
||||||
min-height: 54px !important;
|
min-height: 54px !important;
|
||||||
min-width: 54px !important;
|
min-width: 54px !important;
|
||||||
font-size: 26px !important;
|
font-size: 26px !important;
|
||||||
|
box-shadow: $box-shadow-x-large !important;
|
||||||
z-index: $z-index-sticky-float !important;
|
z-index: $z-index-sticky-float !important;
|
||||||
position: fixed !important;
|
position: fixed !important;
|
||||||
bottom: -5px !important;
|
right: max(20px, calc((100vw - $container-max-width-x-large) / 2 + 48px)) !important;
|
||||||
left: 98vw !important;
|
top: 81px !important;
|
||||||
transform: translate(-120%, -120%) !important;
|
transition: top 0.3s ease !important;
|
||||||
box-shadow: $box-shadow-x-large !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.post-add-button-top {
|
.main-navigation:has(.hide-navbar) ~ .ds-container .post-add-button {
|
||||||
height: 54px !important;
|
top: 20px !important;
|
||||||
width: 54px !important;
|
|
||||||
min-height: 54px !important;
|
|
||||||
min-width: 54px !important;
|
|
||||||
font-size: 26px !important;
|
|
||||||
z-index: $z-index-sticky-float !important;
|
|
||||||
position: fixed !important;
|
|
||||||
top: 80px !important;
|
|
||||||
box-shadow: $box-shadow-x-large !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.top-filter-menu {
|
.top-info-bar {
|
||||||
margin-top: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-info-bar,
|
|
||||||
.top-filter-menu {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
.filterButtonMenu {
|
|
||||||
width: 95%;
|
|
||||||
position: fixed;
|
|
||||||
z-index: $z-index-sticky;
|
|
||||||
margin-top: -45px;
|
|
||||||
padding: 30px 0px 20px 0px;
|
|
||||||
background-color: #f5f4f6;
|
|
||||||
}
|
|
||||||
.newsfeed-controls {
|
.newsfeed-controls {
|
||||||
margin-top: 46px;
|
margin-top: 8px;
|
||||||
|
|
||||||
|
&.newsfeed-controls--no-filter {
|
||||||
|
margin-top: -16px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
.top-info-bar {
|
||||||
|
padding-right: 70px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.main-container .grid-column-helper {
|
.main-container .grid-column-helper {
|
||||||
grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 357px)) !important;
|
grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 357px)) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 656px) {
|
|
||||||
.filterButtonMenu {
|
|
||||||
margin-top: -50px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#my-filter {
|
#my-filter {
|
||||||
max-width: 1028px;
|
max-width: 1028px;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
@ -433,7 +420,7 @@ export default {
|
|||||||
z-index: $z-index-page-submenu;
|
z-index: $z-index-page-submenu;
|
||||||
}
|
}
|
||||||
.grid-margin-top {
|
.grid-margin-top {
|
||||||
margin-top: 26px;
|
margin-top: 8px;
|
||||||
}
|
}
|
||||||
@media screen and (min-height: 401px) {
|
@media screen and (min-height: 401px) {
|
||||||
#my-filter {
|
#my-filter {
|
||||||
@ -475,25 +462,9 @@ export default {
|
|||||||
padding-bottom: 80px;
|
padding-bottom: 80px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@media screen and (max-width: 1200px) {
|
|
||||||
.box-add-button-top {
|
|
||||||
padding-right: 40px;
|
|
||||||
}
|
|
||||||
.post-add-button-top {
|
|
||||||
height: 44px !important;
|
|
||||||
width: 44px !important;
|
|
||||||
min-height: 44px !important;
|
|
||||||
min-width: 44px !important;
|
|
||||||
font-size: 23px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media screen and (max-width: 650px) {
|
@media screen and (max-width: 650px) {
|
||||||
// .top-filter-menu{
|
|
||||||
// margin-top: 24px;
|
|
||||||
// }
|
|
||||||
|
|
||||||
.newsfeed-controls {
|
.newsfeed-controls {
|
||||||
margin-top: 32px;
|
margin-top: 8px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user