This repository has been archived on 2024-07-22. You can view files and clone it, but cannot push or open issues or pull requests.
Zaimki/components/Header.vue

460 lines
18 KiB
Vue
Raw Normal View History

2020-09-11 03:17:29 -07:00
<template>
2021-06-16 07:08:38 -07:00
<div v-if="config.header" class="mb-4">
<header>
2021-05-13 03:09:08 -07:00
<div class="d-none d-lg-flex justify-content-between align-items-center flex-row nav-custom btn-group mb-0">
2022-01-25 13:40:43 -08:00
<nuxt-link v-for="link in links" :key="link.link" :to="link.link" :class="`nav-item btn btn-sm ${link.header ? 'nav-header' : ''} ${isActiveRoute(link) ? 'active' : ''} ${link.header ? 'flex-grow-0' : ''}`">
2021-05-13 03:09:08 -07:00
<h1 v-if="link.header" class="text-nowrap">
2022-01-25 13:40:43 -08:00
<Logo flag/>
<span class="higher"><T>title</T></span>
2021-05-13 03:09:08 -07:00
</h1>
<template v-else>
2021-05-03 07:15:48 -07:00
<Icon :v="link.icon" size="1.6"/>
<br/>
<span class="text-nowrap"><Spelling :text="link.text"/></span>
2021-05-13 03:09:08 -07:00
</template>
</nuxt-link>
<div class="nav-item flex-grow-0">
<VersionDropdown end/>
</div>
2020-09-29 07:27:37 -07:00
</div>
2021-12-12 09:36:01 -08:00
<div class="d-block d-lg-none p-4">
2021-05-13 03:09:08 -07:00
<div class="text-center mb-3">
<nuxt-link to="/">
<h1 class="text-nowrap">
2022-01-25 13:40:43 -08:00
<Logo flag class="me-2"/><span class="higher"><T>title</T></span>
2021-05-13 03:09:08 -07:00
</h1>
</nuxt-link>
<VersionDropdown/>
</div>
2021-01-22 14:54:24 -08:00
<div class="btn-group-vertical d-flex nav-custom mb-2">
2020-09-23 12:34:37 -07:00
<nuxt-link v-for="link in links" :key="link.link" :to="link.link" :class="`btn btn-sm ${isActiveRoute(link) ? 'active' : ''}`">
2020-09-23 11:34:35 -07:00
<Icon :v="link.icon"/>
<Spelling :text="link.textLong || link.text"/>
2020-09-23 11:34:35 -07:00
</nuxt-link>
</div>
</div>
2021-01-21 11:15:55 -08:00
<div :class="['hamburger-menu']" :style="`opacity: ${hamburgerShown ? 1 : 0}`">
<button :class="['btn btn-outline-secondary btn-hamburger', hamburgerActive ? 'active' : '']"
@click.stop="hamburgerActive = !hamburgerActive"
>
<Icon v="bars"/>
</button>
<div :class="['bg border p-3 shadow', hamburgerActive ? '' : 'd-none']">
2021-03-01 13:35:03 -08:00
<div class="btn-group-vertical d-flex nav-custom nav-custom-start mb-2">
2021-01-21 11:15:55 -08:00
<nuxt-link v-for="link in links" :key="link.link" :to="link.link" :class="`btn btn-sm ${isActiveRoute(link) ? 'active' : ''}`">
<Icon :v="link.icon"/>
<Spelling :text="link.textLong || link.text"/>
2021-01-21 11:15:55 -08:00
</nuxt-link>
</div>
</div>
</div>
2021-06-16 07:08:38 -07:00
</header>
2021-12-14 07:04:14 -08:00
<div v-if="config.locale === 'zh' && new Date() < new Date(2022, 0, 1, 0, 0, 0) && $route.path === '/'" class="container">
<div class="alert alert-info my-3">
<p class="h4">
<Icon v="people-carry"/>
Help needed!
</p>
<p class="mb-0">
If you speak Mandarin
(preferably traditional spelling, since simplified can be generated out of it, but not the other way around)
and you'd like to help us with translating new features of zh.pronouns.page,
please send us an email to <a href="mailto:contact@pronouns.page" target="_blank" rel="noopener">contact@pronouns.page</a>
or DM us on Twitter <a href="https://twitter.com/PronounsPage" target="_blank" rel="noopener">@PronounsPage</a>
😉
</p>
2021-07-22 12:49:17 -07:00
</div>
</div>
2021-12-19 15:15:30 -08:00
<div v-if="config.locale === 'pl' && new Date() < new Date(2022, 0, 1, 0, 0, 0) && $route.path === '/'" class="container">
<div class="alert alert-info my-3">
<p class="h3">
<Icon v="zine.svg" :inverse="darkMode"/>
<T>links.zine.headerLong</T>
</p>
<p>
Do końca grudnia zbieramy zgłoszenia tekstów i grafik do niebinarnego zina!
</p>
<p class="mb-0">
<nuxt-link to="/zin" class="btn btn-primary">
<Icon v="info-circle"/>
Więcej info
</nuxt-link>
</p>
</div>
</div>
2021-12-26 07:45:02 -08:00
<div v-if="locales[config.locale].published === false" class="alert alert-warning mb-0 mx-5 text-center">
<Icon v="exclamation-triangle"/>
This language version is still under construction!
</div>
2022-01-01 05:06:36 -08:00
<div v-show="showCensus" class="container">
<div class="alert alert-info mb-0">
<a href="#" class="float-end" @click.prevent="dismissCensus">
<Icon v="times"/>
</a>
<Icon v="user-chart" size="2" class="d-inline-block float-start me-3 mt-2"/>
<T silent>census.banner</T>
</div>
2021-02-01 03:12:16 -08:00
</div>
2021-06-16 07:08:38 -07:00
<div v-if="$user() && $user().bannedReason" class="alert alert-danger mb-0 container">
<p class="h4 mb-2">
<Icon v="ban"/>
<T>ban.header</T>
</p>
<p >
2021-12-02 08:18:25 -08:00
<T>ban.reason</T><T>quotation.colon</T>
2021-06-16 07:08:38 -07:00
{{$user().bannedReason}}
</p>
<p>
2021-12-02 08:18:25 -08:00
<T>ban.termsIntro</T><T>quotation.colon</T>
2021-06-16 07:08:38 -07:00
</p>
<blockquote class="small">
<T>terms.content.content.violations</T>
<template v-for="(violation, i) in forbidden"><T :class="[$user().bannedTerms.includes(violation) ? 'fw-bold' : '']">terms.content.content.violationsExamples.{{violation}}</T><template v-if="i !== forbidden.length - 1">, </template></template>.
2021-06-16 07:08:38 -07:00
</blockquote>
</div>
</div>
2020-10-28 08:22:29 -07:00
<header v-else class="mb-4">
<div class="container">
2022-01-25 13:40:43 -08:00
<h1 class="text-nowrap p-4 mb-0">
<nuxt-link to="/">
2022-01-25 13:40:43 -08:00
<Logo flag class="me-2"/><span class="higher"><T>title</T></span>
</nuxt-link>
</h1>
</div>
2020-10-28 08:22:29 -07:00
</header>
2020-09-11 03:17:29 -07:00
</template>
<script>
import { mapState } from 'vuex'
2021-02-01 03:12:16 -08:00
import {DateTime} from "luxon";
2021-08-12 03:14:34 -07:00
import forbidden from "../src/forbidden";
2020-09-11 03:17:29 -07:00
export default {
2021-01-21 11:15:55 -08:00
data() {
return {
hamburgerActive: false,
hamburgerShown: false,
2021-02-01 03:12:16 -08:00
censusDismissed: false,
2021-08-12 03:14:34 -07:00
forbidden,
2021-01-21 11:15:55 -08:00
};
},
computed: {
...mapState([
'user',
2021-12-19 15:16:23 -08:00
'darkMode',
]),
links() {
const links = [];
links.push({
2021-05-13 03:09:08 -07:00
header: true,
link: '/',
icon: 'home',
text: this.$t('home.header'),
textLong: this.$t('home.link'),
});
2020-09-28 09:29:13 -07:00
2021-08-06 04:30:58 -07:00
if (this.config.pronouns.enabled) {
2021-12-23 03:36:54 -08:00
const extra = ['all', '/' + this.config.pronouns.any, `/${this.config.pronouns.any}:`]
2021-09-28 12:34:25 -07:00
if (this.config.pronouns.null && this.config.pronouns.null.routes) {
for (let route of this.config.pronouns.null.routes) {
extra.push('/' + route);
}
}
2021-12-11 07:57:54 -08:00
if (this.config.pronouns.mirror) {
extra.push('/' + this.config.pronouns.mirror.route)
}
2021-08-06 04:30:58 -07:00
links.push({
link: '/' + this.config.pronouns.route,
icon: 'tags',
text: this.$t('pronouns.header'),
2021-09-05 02:58:37 -07:00
textLong: this.$t('pronouns.headerLong').replace( /(<([^>]+)>)/ig, ''),
2021-09-28 12:34:25 -07:00
extra: extra,
2021-08-06 04:30:58 -07:00
});
}
if (this.config.nouns.enabled) {
const extras = [];
for (let subroute of this.config.nouns.subroutes || []) {
2021-08-30 02:36:57 -07:00
extras.push(`/${subroute}`);
}
links.push({
link: '/' + this.config.nouns.route,
2020-12-18 08:32:18 -08:00
icon: 'book',
text: this.$t('nouns.header'),
textLong: this.$t('nouns.headerLong'),
extra: extras,
});
}
2020-09-28 09:29:13 -07:00
2021-08-30 02:36:57 -07:00
if (this.config.sources.enabled) {
links.push({
link: '/' + this.config.sources.route,
icon: 'books',
text: this.$t('sources.header'),
textLong: this.$t('sources.headerLong'),
});
}
2021-09-25 05:55:53 -07:00
if (this.config.names && this.config.names.enabled && this.config.names.published) {
links.push({
link: '/' + this.config.names.route,
icon: 'signature',
text: this.$t('names.header'),
textLong: this.$t('names.headerLong'),
});
}
2020-09-29 08:59:23 -07:00
2021-05-17 16:01:33 -07:00
if (this.config.faq.enabled && !this.config.links.split) {
links.push({
link: '/' + this.config.faq.route,
icon: 'map-marker-question',
text: this.$t('faq.header'),
textLong: this.$t('faq.headerLong'),
});
}
2020-10-10 09:31:31 -07:00
if (this.config.links.enabled) {
links.push({
link: '/' + this.config.links.route,
icon: 'bookmark',
text: this.$t('links.header'),
textLong: this.$t('links.headerLong'),
2021-05-13 04:54:13 -07:00
extra: [
'/' + this.config.links.academicRoute,
'blog',
'blogEntry',
'blogEntryShortcut',
2021-05-13 04:54:13 -07:00
'/' + this.config.links.mediaRoute,
2021-05-17 16:01:33 -07:00
this.config.links.split ? '/' + this.config.faq.route : '',
2021-08-30 02:36:57 -07:00
this.config.english && this.config.english.enabled ? '/' + this.config.english.route : '',
2021-10-21 11:43:57 -07:00
this.config.links.zine && this.config.links.zine.enabled ? '/' + this.config.links.zine.route : '',
2021-05-13 04:54:13 -07:00
],
});
}
2020-09-29 10:11:46 -07:00
2021-08-30 02:36:57 -07:00
if ((this.config.terminology.enabled && this.config.terminology.published)
|| (this.config.calendar && this.config.calendar.enabled)
2022-01-17 13:50:54 -08:00
|| (this.config.census && this.config.census.enabled)
|| (this.config.inclusive && this.config.inclusive.enabled)
2021-08-30 02:36:57 -07:00
|| (this.config.people && this.config.people.enabled)
) {
2021-09-14 03:23:08 -07:00
const extra = [
2022-01-17 13:50:54 -08:00
this.config.terminology && this.config.terminology.enabled ? '/' + this.config.terminology.route : '',
this.config.calendar && this.config.calendar.enabled ? '/' + this.config.calendar.route : '',
2021-09-14 03:23:08 -07:00
this.config.census && this.config.census.enabled ? '/' + this.config.census.route : '',
2022-01-17 13:50:54 -08:00
this.config.inclusive && this.config.inclusive.enabled ? '/' + this.config.inclusive.route : '',
2021-09-14 03:23:08 -07:00
this.config.people && this.config.people.enabled ? '/' + this.config.people.route : '',
2021-11-19 02:59:28 -08:00
'/' + this.config.contact.team.route,
2021-09-14 03:23:08 -07:00
];
if (this.config.community) {
links.push({
link: '/' + this.config.community.route,
icon: 'users',
text: this.$t('community.header'),
textLong: this.$t('community.headerLong'),
extra: extra,
});
} else if (this.config.calendar && this.config.calendar.enabled) {
links.push({
link: '/' + this.config.calendar.route,
icon: 'calendar-star',
text: this.$t('calendar.header'),
textLong: this.$t('calendar.headerLong'),
extra: extra,
});
}
2020-12-18 02:34:58 -08:00
}
if (this.config.contact.enabled) {
links.push({
link: '/' + this.config.contact.route,
icon: 'comment-alt-smile',
text: this.$t('contact.header'),
});
}
2020-09-28 09:29:13 -07:00
if (this.config.user.enabled) {
links.push({
link: '/' + this.config.user.route,
icon: 'user',
text: this.user ? '@' + this.user.username : this.$t('user.header'),
textLong: this.user ? '@' + this.user.username : this.$t('user.headerLong'),
extra: ['/editor', this.$user() ? '/@' + this.$user().username : null],
});
}
2020-10-13 12:49:08 -07:00
return links;
},
2021-02-01 03:12:16 -08:00
showCensus() {
if (!process.client) {
return false;
}
const finished = !!parseInt(window.localStorage.getItem('census-finished') || 0);
const dismissed = !!parseInt(window.localStorage.getItem('census-dismissed') || 0);
const alreadyIn = this.$route.path === '/' + this.config.census.route;
if (!this.config.census.enabled || finished || dismissed || this.censusDismissed || alreadyIn) {
return false;
}
const start = DateTime.fromISO(this.config.census.start).toLocal();
const end = DateTime.fromISO(this.config.census.end).toLocal();
const now = DateTime.utc().setZone(this.config.format.timezone);
return now >= start && now <= end;
},
2020-09-23 11:34:35 -07:00
},
methods: {
isActiveRoute(link) {
return decodeURIComponent(this.$route.path) === link.link
|| (link.extra && this.$route.name && link.extra.includes(this.$route.name.split(':')[0]))
|| (link.extra || []).includes(decodeURIComponent(this.$route.path))
2021-12-23 03:36:54 -08:00
|| (link.extra || []).filter(x => x && (
decodeURIComponent(this.$route.path).startsWith(x + '/')
|| decodeURIComponent(this.$route.path).startsWith(x + ':'))
).length;
2020-09-23 11:34:35 -07:00
},
2021-01-21 11:15:55 -08:00
documentClicked() {
if (this.hamburgerActive) {
this.hamburgerActive = false
}
},
updateShown() {
const st = document.body.scrollTop || document.querySelector('html').scrollTop;
this.hamburgerShown = st > 300;
},
2021-02-01 03:12:16 -08:00
dismissCensus() {
window.localStorage.setItem('census-dismissed', '1');
this.censusDismissed = true;
}
2021-01-21 11:15:55 -08:00
},
created() {
if (process.client) {
document.addEventListener('click', this.documentClicked);
this.updateShown();
window.addEventListener('scroll', this.updateShown);
}
},
destroyed() {
if (process.client) {
document.removeEventListener('click', this.documentClicked);
document.removeEventListener('scroll', this.updateShown);
}
2020-09-23 11:34:35 -07:00
},
2020-09-11 03:17:29 -07:00
}
</script>
2020-09-23 11:34:35 -07:00
<style lang="scss" scoped>
@import "assets/variables";
2020-09-23 11:34:35 -07:00
2021-05-03 07:15:48 -07:00
header {
2021-05-13 03:09:08 -07:00
padding: 0;
2021-05-03 07:15:48 -07:00
width: 100%;
}
2021-05-13 03:09:08 -07:00
@include media-breakpoint-down('lg', $grid-breakpoints) {
2020-12-23 12:47:51 -08:00
h1 {
font-size: 2rem;
}
2020-09-23 11:34:35 -07:00
.nav-custom {
.btn {
2021-03-01 13:35:03 -08:00
border-inline-start: 1px solid $gray-500;
2020-09-23 11:34:35 -07:00
border-radius: 0;
&:hover, &:focus, &.active {
2021-03-01 13:35:03 -08:00
border-inline-start: 3px solid $primary;
padding-inline-start: calc(#{$btn-padding-x-sm} - 2px);
2020-09-23 11:34:35 -07:00
color: $primary;
}
text-align: left;
}
}
2021-05-13 03:09:08 -07:00
.hamburger-menu {
position: fixed;
top: $spacer;
left: $spacer;
z-index: 1030;
transition: all .5s ease-in-out;
.bg {
background-color: rgba($white, .9)
}
2021-05-13 03:09:08 -07:00
.btn-hamburger {
&:not(:active):not(:hover):not(:focus):not(.active) {
background-color: $white;
}
&.active {
background-color: $secondary;
}
}
}
2020-09-23 11:34:35 -07:00
}
2021-03-01 13:35:03 -08:00
.nav-custom-start {
2021-01-21 11:15:55 -08:00
.btn {
2021-03-01 13:35:03 -08:00
border-inline-start: 1px solid $gray-500;
2021-01-21 11:15:55 -08:00
border-radius: 0;
&:hover, &:focus, &.active {
2021-03-01 13:35:03 -08:00
border-inline-start: 3px solid $primary;
padding-inline-start: calc(#{$btn-padding-x-sm} - 2px);
2021-01-21 11:15:55 -08:00
color: $primary;
}
text-align: left;
}
}
2021-05-13 03:09:08 -07:00
@include media-breakpoint-up('lg', $grid-breakpoints) {
header {
position: fixed;
2022-03-19 14:10:26 -07:00
z-index: 99;
2021-05-13 03:09:08 -07:00
top: 0;
left: 0;
background-color: rgba($white, .9);
2021-12-03 06:15:19 -08:00
box-shadow: $box-shadow;
2021-05-13 03:09:08 -07:00
}
2021-03-01 13:35:03 -08:00
.nav-custom:not(.nav-custom-start) {
2021-05-13 03:09:08 -07:00
.nav-item {
2020-09-23 11:34:35 -07:00
border-bottom: 1px solid $gray-500;
border-radius: 0;
2021-05-13 03:09:08 -07:00
&.btn {
&:hover, &:focus, &.active {
border-bottom: 3px solid $primary;
padding-bottom: calc(#{$btn-padding-y-sm} - 2px);
color: $primary;
}
}
height: $header-height;
padding-top: 1.2rem;
2022-01-25 13:40:43 -08:00
&.nav-header {
padding-top: 0.6rem;
}
2021-05-13 03:09:08 -07:00
margin-top: 3px;
&:first-child, &:last-child {
padding-left: 1rem;
padding-right: 1rem;
2020-09-23 11:34:35 -07:00
}
}
}
2021-05-13 03:09:08 -07:00
.hamburger-menu {
display: none;
2020-12-25 05:38:23 -08:00
}
}
2021-01-21 11:15:55 -08:00
2021-05-13 03:09:08 -07:00
h1 {
text-decoration: none;
2022-01-25 13:40:43 -08:00
margin-bottom: .5em;
2021-05-13 03:09:08 -07:00
.higher {
position: relative;
top: -0.1em;
2021-01-21 11:15:55 -08:00
}
}
2020-09-23 11:34:35 -07:00
</style>