Skip to content
Snippets Groups Projects
Home.vue 12.3 KiB
Newer Older
  <main class="main pusher" v-title="labels.title">
    <section :class="['ui', 'head', {'with-background': banner}, 'vertical', 'center', 'aligned', 'stripe', 'segment']" :style="headerStyle">
      <div class="segment-content">
        <h1 class="ui center aligned large header">
          <translate translate-context="Content/Home/Header"
            :translate-params="{podName: podName}">
            Welcome to %{ podName }!
          </translate>
          <div v-if="shortDescription" class="sub header">
            {{ shortDescription }}
          </div>
    </section>
    <section class="ui vertical stripe segment">
      <div class="ui stackable grid">
        <div class="ten wide column">
          <h3 class="header">
            <translate translate-context="Content/Home/Header">About this Funkwhale pod</translate>
          </h3>
          <div class="ui raised segment" id="pod">
            <div class="ui stackable grid">
              <div class="eight wide column">
                <p v-if="!truncatedDescription">
                  <translate translate-context="Content/Home/Paragraph">No description available.</translate>
                </p>
                <template v-if="truncatedDescription || rules">
                  <div v-if="truncatedDescription" v-html="truncatedDescription"></div>
                  <div v-if="truncatedDescription" class="ui hidden divider"></div>
                  <div class="ui relaxed list">
                    <div class="item" v-if="truncatedDescription">
                      <i class="arrow right grey icon"></i>
                      <div class="content">
                        <router-link class="ui link" :to="{name: 'about'}">
                          <translate translate-context="Content/Home/Link">Learn more</translate>
                        </router-link>
                      </div>
                    </div>
                    <div class="item" v-if="rules">
                      <i class="book open grey icon"></i>
                      <div class="content">
                        <router-link class="ui link" v-if="rules" :to="{name: 'about', hash: '#rules'}">
                          <translate translate-context="Content/Home/Link">Server rules</translate>
                        </router-link>
                      </div>
                    </div>
                  </div>
                </template>
              </div>
              <div class="eight wide column">
                <template v-if="stats">
                  <h3 class="sub header">
                    <translate translate-context="Content/Home/Header">Statistics</translate>
                  </h3>
                  <p>
                    <i class="user grey icon"></i><translate translate-context="Content/Home/Stat" :translate-params="{count: stats.users.toLocaleString($store.state.ui.momentLocale) }" :translate-n="stats.users" translate-plural="%{ count } active users">%{ count } active user</translate>
                  </p>
                  <p>
                    <i class="music grey icon"></i><translate translate-context="Content/Home/Stat" :translate-params="{count: parseInt(stats.hours).toLocaleString($store.state.ui.momentLocale)}" :translate-n="parseInt(stats.hours)" translate-plural="%{ count } hours of music">%{ count } hour of music</translate>
                  </p>

                </template>
                <template v-if="contactEmail">
                  <h3 class="sub header">
                    <translate translate-context="Content/Home/Header/Name">Contact</translate>
                  </h3>
                  <i class="at grey icon"></i>
                  <a :href="`mailto:${contactEmail}`">{{ contactEmail }}</a>
                </template>

              </div>

        <div class="six wide column">
          <img class="ui image" src="../assets/network.png" />
      <div class="ui hidden divider"></div>
      <div class="ui hidden divider"></div>
      <div class="ui stackable grid">
        <div class="four wide column">
          <h3 class="header">
            <translate translate-context="Footer/*/Title/Short">About Funkwhale</translate>
          </h3>
          <p v-translate translate-context="Content/Home/Paragraph">This pod runs Funkwhale, a community-driven project that lets you listen and share music and audio within a decentralized, open network.</p>
          <p v-translate translate-context="Content/Home/Paragraph">Funkwhale is free and developped by a friendly community of volunteers.</p>
          <a target="_blank" rel="noopener" href="https://funkwhale.audio">
            <i class="external alternate icon"></i>
            <translate translate-context="Content/Home/Link">Visit funkwhale.audio</translate>
          </a>
        <div class="four wide column">
          <h3 class="header">
            <translate translate-context="Head/Login/Title">Log In</translate>
          </h3>
          <login-form button-classes="basic green" :show-signup="false"></login-form>
          <div class="ui hidden clearing divider"></div>
        </div>
        <div class="four wide column">
          <h3 class="header">
            <translate translate-context="*/Signup/Title">Sign up</translate>
          </h3>
          <template v-if="openRegistrations">
            <p>
              <translate translate-context="Content/Home/Paragraph">Sign up now to keep a track of your favorites, create playlists, discover new content and much more!</translate>
            </p>
            <p v-if="defaultUploadQuota">
              <translate translate-context="Content/Home/Paragraph" :translate-params="{quota: humanSize(defaultUploadQuota * 1000 * 1000)}">Users on this pod also get %{ quota } of free storage to upload their own content!</translate>
            </p>
            <signup-form button-classes="basic green" :show-login="false"></signup-form>
          </template>
          <div v-else>
            <p translate-context="Content/Home/Paragraph">Registrations are closed on this pod. You can signup on another pod using the link below.</p>
            <a target="_blank" rel="noopener" href="https://funkwhale.audio/#get-started">
              <i class="external alternate icon"></i>
              <translate translate-context="Content/Home/Link">Find another pod</translate>
            </a>

        <div class="four wide column">
          <h3 class="header">
            <translate translate-context="Content/Home/Header">Useful links</translate>
          </h3>
          <div class="ui relaxed list">
            <div class="item">
              <i class="headphones icon"></i>
              <div class="content">
                <router-link v-if="anonymousCanListen" class="header" to="/library">
                  <translate translate-context="Content/Home/Link">Browse public content</translate>
                </router-link>
                <div class="description">
                  <translate translate-context="Content/Home/Link">Listen to public albums and playlists shared on this pod</translate>
                </div>
              </div>
            <div class="item">
              <i class="mobile alternate icon"></i>
              <div class="content">
                <a class="header" href="https://funkwhale.audio/apps" target="_blank" rel="noopener">
                  <translate translate-context="Content/Home/Link">Mobile apps</translate>
                </a>
                <div class="description">
                  <translate translate-context="Content/Home/Link">Use Funkwhale on other devices with our apps</translate>
                </div>
              </div>
            <div class="item">
              <i class="book icon"></i>
              <div class="content">
                <a class="header" href="https://docs.funkwhale.audio/users/index.html" target="_blank" rel="noopener">
                  <translate translate-context="Content/Home/Link">User guides</translate>
                </a>
                <div class="description">
                  <translate translate-context="Content/Home/Link">Discover everything you need to know about Funkwhale and its features</translate>
                </div>
              </div>
    <section v-if="anonymousCanListen" class="ui vertical stripe segment">
      <album-widget :filters="{playable: true, ordering: '-creation_date'}" :limit="10">
        <template slot="title"><translate translate-context="Content/Home/Title">Recently added albums</translate></template>
        <router-link to="/library">
          <translate translate-context="Content/Home/Link">View more…</translate>
          <div class="ui hidden divider"></div>
        </router-link>
      </album-widget>
    </section>
import $ from 'jquery'
import _ from '@/lodash'
import {mapState} from 'vuex'
import showdown from 'showdown'
import AlbumWidget from "@/components/audio/album/Widget"
import LoginForm from "@/components/auth/LoginForm"
import SignupForm from "@/components/auth/SignupForm"
import {humanSize } from '@/filters'

  components: {
    AlbumWidget,
    LoginForm,
    SignupForm,
  },
  data () {
      markdown: new showdown.Converter(),
      excerptLength: 2, // html nodes,
      humanSize
Eliot Berriot's avatar
Eliot Berriot committed
  computed: {
    ...mapState({
      nodeinfo: state => state.instance.nodeinfo,
    }),
Eliot Berriot's avatar
Eliot Berriot committed
      return {
jovuit's avatar
jovuit committed
        title: this.$pgettext('Head/Home/Title', "Welcome")
    podName() {
      return _.get(this.nodeinfo, 'metadata.nodeName') || "Funkwhale"
    },
    banner () {
      return _.get(this.nodeinfo, 'metadata.banner')
    },
    shortDescription () {
      return _.get(this.nodeinfo, 'metadata.shortDescription')
    },
    longDescription () {
      return _.get(this.nodeinfo, 'metadata.longDescription')
    },
    rules () {
      return _.get(this.nodeinfo, 'metadata.rules')
    },
    truncatedDescription () {
      if (!this.longDescription) {
        return
      }
      let doc = this.markdown.makeHtml(this.longDescription)
      let nodes = $.parseHTML(doc)
      let excerptParts = []
      let handled = 0
      nodes.forEach((n) => {
        let content = n.innerHTML || n.nodeValue
        if (handled < this.excerptLength && content.trim()) {
          excerptParts.push(n)
          handled += 1
        }
      })
      return excerptParts.map((p) => { return p.outerHTML }).join('')
    },
    stats () {
      let data = {
        users: _.get(this.nodeinfo, 'usage.users.activeMonth', null),
        hours: _.get(this.nodeinfo, 'metadata.library.music.hours', null),
      }
      if (data.users === null || data.artists === null) {
        return
      }
      return data
    },
    contactEmail () {
      return _.get(this.nodeinfo, 'metadata.contactEmail')
    },
    defaultUploadQuota () {
      return _.get(this.nodeinfo, 'metadata.defaultUploadQuota')
    },
    anonymousCanListen () {
      return _.get(this.nodeinfo, 'metadata.library.anonymousCanListen')
    },
    openRegistrations () {
      return _.get(this.nodeinfo, 'openRegistrations')
    },
    headerStyle() {
      if (!this.banner) {
        return ""
      }
      return (
        "background-image: url(" +
        this.$store.getters["instance/absoluteUrl"](this.banner) +
        ")"
      )
    },
  },
  watch: {
    '$store.state.auth.authenticated': {
      handler (v) {
        if (v) {
          console.log('Authenticated, redirecting to /library…')
          this.$router.push('/library')
        }
      },
      immediate: true
    }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
.ui.list .list.icon {

h1.header, h1 .sub.header {
  text-shadow: 1px 1px 2px rgba(0,0,0,.8);
  color: #fff !important;
}
h1.ui.header {
  @include media(">tablet") {
    font-size: 3em;
  }
}
h1.ui.header .sub.header {
  font-size: 0.8em;
}
.main.pusher {
  margin-top: 0;
  min-height: 10em;
}
section.segment.head {
  padding: 8em 3em;
  background: linear-gradient(90deg, rgba(40,88,125,1) 0%, rgba(64,130,180,1) 100%);
  background-repeat: no-repeat;
  background-size: cover;
}
#pod {
  font-size: 110%;
  display: block;
}