loomio/loomio

View on GitHub
vue/src/app.vue

Summary

Maintainability
Test Coverage
<script lang="js">
import AppConfig from '@/shared/services/app_config';
import AuthModalMixin from '@/mixins/auth_modal';
import EventBus from '@/shared/services/event_bus';
import AbilityService from '@/shared/services/ability_service';
import Session from '@/shared/services/session';
import Flash from '@/shared/services/flash';
import { each, compact, truncate } from 'lodash-es';
import openModal from '@/shared/helpers/open_modal';
import { initLiveUpdate, closeLiveUpdate } from '@/shared/helpers/message_bus';

export default {
  mixins: [AuthModalMixin],
  data() {
    return {pageError: null};
  },

  created() {
    if (this.$route.query.locale) { Session.updateLocale(this.$route.query.locale); }

    if (Session.user().experiences.darkMode != null) {
      this.$vuetify.theme.dark = Session.user().experiences['darkMode'];
    } else {
      this.$vuetify.theme.dark = (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches);
    }

    return each(AppConfig.theme.vuetify, (value, key) => {
      if (value) { this.$vuetify.theme.themes.light[key] = value; }
      if (value) { this.$vuetify.theme.themes.dark[key] = value; }
      return true;
    });
  },

  mounted() {
    initLiveUpdate();
    if (!Session.isSignedIn() && this.shouldForceSignIn()) { this.openAuthModal(true); }
    EventBus.$on('currentComponent',     this.setCurrentComponent);
    EventBus.$on('openAuthModal',     () => this.openAuthModal());
    EventBus.$on('pageError', error => { return this.pageError = error; });
    EventBus.$on('signedIn',          () => { return this.pageError = null; });
    EventBus.$on('VueForceUpdate',    () => {
      this.$nextTick(() => {this.$forceUpdate(); });
    });
    if (AppConfig.flash.notice) { Flash.success(AppConfig.flash.notice); }
  },

  destroyed() {
    return closeLiveUpdate();
  },

  watch: {
    '$route'() {
      return this.pageError = null;
    }
  },

  methods: {
    setCurrentComponent(options) {
      this.pageError = null;
      const title = truncate(options.title || this.$t(options.titleKey), {length: 300});
      document.querySelector('title').text = compact([title, AppConfig.theme.site_name]).join(' | ');

      AppConfig.currentGroup      = options.group;
      AppConfig.currentDiscussion = options.discussion;
      return AppConfig.currentPoll       = options.poll;
    },

    shouldForceSignIn(options = {}) {
      if (this.$route.query.sign_in) { return true; }
      if ((AppConfig.pendingIdentity || {}).identity_type != null) { return true; }
      if (Session.isSignedIn()) { return false; }

      switch (this.$route.path) {
        case '/email_preferences': return (Session.user().restricted == null);
        case '/dashboard':      
             case '/inbox':          
             case '/profile':        
             case '/polls':          
             case '/p/new':      
             case '/g/new': return true;
      }
    }
  }
};

</script>

<template lang="pug">
v-app.app-is-booted
  system-notice
  navbar
  sidebar
  router-view(v-if="!pageError")
  common-error(v-if="pageError" :error="pageError")
  v-spacer
  common-footer
  modal-launcher
  common-flash
</template>

<style lang="sass">
@import '@/css/utilities.scss'
@import '@/css/roboto.css'
@import '@/css/thumbicons.css'
@import '@/css/print.scss'

.v-application .text-body-3
  font-size: 0.9375rem !important
  letter-spacing: normal !important
  font-weight: 400

.v-application .text-body-4
  font-size: 1rem !important
  letter-spacing: normal !important
  font-weight: 400

h1:focus, h2:focus, h3:focus, h4:focus, h5:focus, h6:focus
  outline: 0
a
  text-decoration: none

.lmo-relative
  position: relative

.text-almost-black
  color: rgba(0, 0, 0, 0.87)
  
.max-width-640
  max-width: 640px !important
.max-width-800
  max-width: 800px !important
.max-width-1024
  max-width: 1024px !important

@media (prefers-color-scheme: dark)
  body
    background-color: #000

@media print
  .lmo-no-print
    display: none !important

</style>