Version 1.2

This commit is contained in:
samcm 2017-06-19 22:04:32 +10:00
parent b16f2aceeb
commit d30a210cea
19 changed files with 164 additions and 88 deletions

View File

@ -25,7 +25,7 @@ module.exports = {
env: require('./dev.env'),
port: 8080,
autoOpenBrowser: true,
assetsSubDirectory: 'static',
assetsSubDirectory: 'ptweb',
assetsPublicPath: '/',
proxyTable: {},
// CSS Sourcemaps off by default because relative paths are "buggy"

View File

@ -48,7 +48,6 @@
"socket.io-client": "^2.0.2",
"stylus": "^0.54.5",
"stylus-loader": "^3.0.1",
"sweet-modal-vue": "^1.1.0",
"url-loader": "^0.5.8",
"vue-clipboards": "^1.0.2",
"vue-loader": "^11.3.4",

View File

@ -1,12 +1,12 @@
<template>
<v-app dark>
<v-navigation-drawer temporary v-model="drawer" dark >
<v-navigation-drawer temporary v-model="drawer" dark disable-route-watcher>
<leftsidebar></leftsidebar>
</v-navigation-drawer>
<v-navigation-drawer persistent v-model="drawerRight" light right light enable-resize-watcher>
<v-navigation-drawer style="padding:0" persistent v-model="drawerRight" light right light disable-route-watcher>
<drawerright></drawerright>
</v-navigation-drawer>
<v-toolbar light>
<v-toolbar light fixed>
<v-toolbar-side-icon light @click.native.stop="drawer = !drawer"></v-toolbar-side-icon>
<v-toolbar-title class="white--text">PlexTogether</v-toolbar-title>
<v-toolbar-items>
@ -19,6 +19,11 @@
<v-list-tile>
<v-list-tile-title v-text="item.title"></v-list-tile-title>
</v-list-tile>
</v-list-item>
<v-list-item v-if="shortUrl" v-clipboard="shortUrl">
<v-list-tile>
<v-list-tile-title primary v-text="Invite"></v-list-tile-title>
</v-list-tile>
</v-list-item>
</v-list>
</v-menu>
@ -31,14 +36,19 @@
</v-toolbar>
<main v-bind:style="mainStyle">
<v-container style="padding:0" v-bind:style="containerStyle" fluid>
<router-view></router-view>
<router-view></router-view>
<v-snackbar
bottom
:timeout="4000"
v-model="snackbar"
> <div style="text-align:center;width:100%">{{snackbarMsg}}</div>
</v-snackbar>
</v-container>
</main>
</v-app>
</template>
<script>
// Custom css
import './assets/css/styleNew.css'
@ -58,14 +68,15 @@
drawerRight: false,
right: null,
fixed: false,
initialized: false,
initialized: false,
snackbar: false,
snackbarMsg: false,
items: [
{
title: 'Preferences'
},
{
title: 'Refresh Plex Devices'
},
{
title: 'Signout'
}
@ -99,6 +110,10 @@
this.$store.commit('SET_AUTOJOINPASSWORD', this.$route.query.ptpassword)
this.$store.commit('SET_AUTOJOINURL', this.$route.query.ptserver)
}
window.EventBus.$on('notification', (msg) => {
this.snackbarMsg = msg
this.snackbar = true
})
},
watch: {
showRightDrawerButton: function () {
@ -125,8 +140,8 @@
return this.$store.state.plex.user.thumb
},
logo: function () {
return 'static/logo-small-light.png'
},
return 'ptweb/logo-small-light.png'
},
isPlayer: function () {
console.log('Router path is ' + this.$route.path)
if (this.$route.path == '/') {

View File

@ -122,7 +122,7 @@
return this.$store.state.plex.user.thumb
},
logo: function () {
return 'static/logo-small-light.png'
return 'ptweb/logo-small-light.png'
},
isPlayer: function () {
console.log('Router path is ' + this.$route.path)

View File

@ -8,8 +8,8 @@
</v-layout>
<div v-if="!browsingContent && contents" class="mt-3">
<v-layout class="row" row wrap>
<v-flex xs12 md4 xl2 lg3 class="pb-3" v-for="content in contents.MediaContainer.Metadata" :key="content">
<plexthumb :content="content" :server="server" type="thumb" :height="'25em'" @contentSet="setContent(content)"></plexthumb>
<v-flex xs4 md3 xl1 lg2 class="pb-3" v-for="content in contents.MediaContainer.Metadata" :key="content">
<plexthumb :content="content" :server="server" type="thumb" @contentSet="setContent(content)"></plexthumb>
</v-flex>
</v-layout>
<v-layout row>

View File

@ -28,8 +28,8 @@
<v-divider></v-divider>
<div>
<v-layout class="row mt-3" row wrap>
<v-flex xs6 md3 xl2 lg2 class="pb-3" v-for="content in contents.MediaContainer.Metadata" :key="content">
<plexthumb :content="content" :server="server" type="thumb" :height="'15em'" fullTitle @contentSet="setContent(content)"></plexthumb>
<v-flex xs6 md3 xl2 lg1 class="pb-3" v-for="content in contents.MediaContainer.Metadata" :key="content">
<plexthumb :content="content" :server="server" type="thumb" fullTitle @contentSet="setContent(content)"></plexthumb>
</v-flex>
</v-layout>
</div>

View File

@ -26,8 +26,8 @@
</v-card>
<h4 class="mt-3"> Episodes </h4>
<v-layout class="row" row wrap>
<v-flex xs6 md3 xl2 lg2 class="pb-3" v-for="content in contents.MediaContainer.Metadata" :key="content">
<plexthumb :content="content" :server="server" type="thumb" :height="'15em'" @contentSet="setContent(content)"></plexthumb>
<v-flex xs4 md3 xl1 lg1 class="pb-3" v-for="content in contents.MediaContainer.Metadata" :key="content">
<plexthumb :content="content" :server="server" type="thumb" @contentSet="setContent(content)"></plexthumb>
</v-flex>
</v-layout>
</div>
@ -77,7 +77,7 @@
getArtUrl (object) {
var w = Math.round(Math.max(document.documentElement.clientWidth, window.innerWidth || 0));
var h = Math.round(Math.max(document.documentElement.clientHeight, window.innerHeight || 0));
return this.server.getUrlForLibraryLoc(this.contents.MediaContainer.banner, w / 3, h / 2, 10)
return this.server.getUrlForLibraryLoc(this.contents.MediaContainer.banner, w / 1, h / 1, 10)
},
getSeasons () {
if (this.contents.MediaContainer.size == 1){

View File

@ -29,15 +29,14 @@
<h4 v-if="subsetOnDeck(3).length > 0"> On Deck </h4>
<v-layout v-if="onDeck" row wrap>
<v-flex xs12 md4 xl4 lg4 class="pb-3" v-for="content in subsetOnDeck(3)" :key="content">
<plexthumb :content="content" :server="server" type="art" :height="'30em'" @contentSet="setContent(content)"></plexthumb>
<plexthumb :content="content" :server="server" type="art" :height="25" @contentSet="setContent(content)"></plexthumb>
</v-flex>
</v-layout>
<v-divider v-if="subsetRecentlyAdded(3).length > 0" class="mt-3 ma-2"></v-divider>
<h4 v-if="subsetRecentlyAdded(3).length > 0"> Recently Added </h4>
<v-layout v-if="recentlyAdded" class="row" row wrap>
<v-flex xs6 md4 xl2 lg3 class="pb-3" height="15em" v-for="content in subsetRecentlyAdded(12)" :key="content">
<plexthumb :content="content" :server="server" type="thumb" @contentSet="setContent(content)"></plexthumb>
<v-flex xs4 md3 xl1 lg1 class="pb-3" v-for="content in subsetRecentlyAdded(12)" :key="content">
<plexthumb :content="content" :server="server" type="thumb" locked @contentSet="setContent(content)"></plexthumb>
</v-flex>
</v-layout>
</div>

View File

@ -1,6 +1,6 @@
<template>
<div class="portrait" ref="root">
<v-card v-on:click="emitContentClicked(content)" class="grey darken-4" :img="getImg(content)" :height="height || '20em'">
<v-card v-on:click="emitContentClicked(content)" class="grey darken-4" :img="getImg(content)" :height="calculatedHeight">
<div class="pt-content-unwatched pt-orange unwatched" v-if="showUnwatchedFlag">
<span class="pa-2 black--text">
<span>
@ -13,14 +13,15 @@
</v-card-row>
<v-card-column style="background: rgba(0, 0, 0, .8);">
<v-card-row :height="'4em'" style="position:relative">
<v-card-row :height="bottomCalculatedHeight" style="position:relative;" class="ma-0">
<v-progress-linear style="position:absolute; top:0; width:100%" class="pa-0 ma-0 pt-content-progress" v-if="showProgressBar" height="2" :value="unwatchedPercent"></v-progress-linear>
<v-layout row wrap class="text-xs-left pa-1" style="display:block; max-width:100%">
<v-flex xs12>
<div v-tooltip:top="{ html: getTitle(content) }" class="truncate" style="font-size:1.3em;">{{ getTitle(content) }}</div>
<v-layout row wrap class="text-xs-left ma-1" style="margin:0; display:block; max-width:100%; height:100%">
<v-flex xs12 style="height:50%" ref="topText" class="pa-0 ma-1">
<div v-tooltip:top="{ html: getTitle(content) }" class="truncate" :style="fontSizeTop">{{ getTitle(content) }}</div>
</v-flex>
<v-flex xs12>
<div class="truncate" style="font-size:0.9em">{{ getUnder(content) }}</div>
<v-flex xs12 style="height:50%" ref="bottomText" class="pa-0 ma-1">
<div class="truncate" style="opacity:0.75" :style="fontSizeBottom">{{ getUnder(content) }}</div>
</v-flex>
</v-layout>
</v-card-row>
@ -46,7 +47,7 @@
export default {
props: ['library', 'showServer', 'content', 'type', 'server', 'height', 'fullTitle', 'search'],
props: ['library', 'showServer', 'content', 'type', 'server', 'height', 'fullTitle', 'search', 'locked'],
components: {
},
created () {
@ -54,12 +55,17 @@
data () {
return {
fullheight: null,
fullwidth: null
fullwidth: null,
toptextheight: null,
bottomtextheight: null
}
},
mounted () {
this.fullheight = this.$refs.root.offsetHeight
this.fullwidth = this.$refs.root.offsetWidth
this.fullwidth = this.$refs.root.offsetWidth
this.toptextheight = this.$refs.topText.offsetHeight
this.bottomtextheight = this.$refs.bottomText.offsetHeight
},
beforeDestroy () {
@ -82,11 +88,59 @@
return false
}
},
fakeRowHeight (){
fontSizeTop () {
return {'font-size':(this.toptextheight * 0.8) + 'px'}
},
fontSizeBottom () {
return {'font-size':(this.bottomtextheight * 0.6) + 'px'}
},
fullCalculatedHeightRaw (){
if (this.height){
return parseInt(this.height) - 4 + 'em'
}
return '16em'
return this.height
}
if (this.content.type == 'movie'){
return Math.round(this.fullwidth * 1.77)
}
if (this.content.type == 'episode'){
return Math.round(this.fullwidth * 0.7)
}
return Math.round(this.fullwidth * 1.5)
},
fakeRowHeight (){
if (this.height){
return Math.round(this.height * 0.78) + 'em'
}
if (this.content.type == 'movie'){
return Math.round(this.fullwidth * 1.77 * 0.78) + 'px'
}
if (this.content.type == 'episode'){
return Math.round(this.fullwidth * 0.7 * 0.78) + 'px'
}
return Math.round((this.fullwidth * 1.5 * 0.78)) + 'px'
},
calculatedHeight (){
if (this.height){
return this.height + 'em'
}
if (this.content.type == 'movie'){
return Math.round(this.fullwidth * 1.77) + 'px'
}
if (this.content.type == 'episode'){
return Math.round(this.fullwidth * 0.7) + 'px'
}
return Math.round(this.fullwidth * 1.5) + 'px'
},
bottomCalculatedHeight (){
if (this.height){
return Math.round(this.height * 0.22) + 'em'
}
if (this.content.type == 'movie'){
return Math.round((this.fullwidth * 1.77) * 0.22) + 'px'
}
if (this.content.type == 'episode'){
return Math.round(this.fullwidth * 0.7 * 0.22) + 'px'
}
return Math.round(this.fullwidth * 1.5 * 0.22) + 'px'
},
showProgressBar (){
if (this.content.type == 'movie' || this.content.type == 'episode'){

View File

@ -67,7 +67,7 @@
},
logo: function () {
return 'static/plexlogo.png'
return 'ptweb/plexlogo.png'
},
},
mounted: function () {

View File

@ -138,15 +138,15 @@
let difference = Math.abs(current - (slidingTime))
if (current < slidingTime) {
// Speed up
playbackSpeed = playbackSpeed + 0.001
playbackSpeed = playbackSpeed + 0.0005
if (that.player.playbackRate() < 1.3) {
that.player.playbackRate(playbackSpeed)
}
}
if (current > slidingTime) {
// Slow down
playbackSpeed = playbackSpeed - 0.001
if (that.player.playbackRate() > 0.1) {
playbackSpeed = playbackSpeed - 0.0005
if (that.player.playbackRate() > 0.95) {
that.player.playbackRate(playbackSpeed)
}
}

View File

@ -13,7 +13,7 @@
<div style="text-align:center" class="pt-4">
<h6 style="text-align:initial">Sync Flexibility</h6>
<div> {{ syncflexability }}</div>
<v-slider class="pa-0 ma-0" v-model="syncflexability" :min="500" :max="10000"
<v-slider class="pa-0 ma-0" v-model="syncflexability" :min="100" :max="10000"
hint="Sets the acceptable distance away from the host in milliseconds. Default is 3000ms (3 seconds)."
light
persistent-hint>
@ -52,7 +52,7 @@
return this.$store
},
logo: function () {
return 'static/logo-small-light.png'
return 'ptweb/logo-small-light.png'
},
appVersion () {
return this.$store.state.appVersion

View File

@ -102,9 +102,9 @@
},
logo: function () {
if (this.$store.getters.getSettingDARKMODE) {
return 'static/logo-long-light.png'
return 'ptweb/logo-long-light.png'
}
return 'static/logo-long-dark.png'
return 'ptweb/logo-long-dark.png'
},
ptConnected: function () {
return this.$store.getters.getConnected

View File

@ -127,7 +127,7 @@
return this.$store
},
logo: function () {
return 'static/logo-long-light.png'
return 'ptweb/logo-long-light.png'
},
playercount: function () {
if (this.$store.state.plex && this.$store.state.plex.gotDevices) {

View File

@ -74,7 +74,7 @@
},
computed: {
logo: function () {
return 'static/logo-long-light.png'
return 'ptweb/logo-long-light.png'
},
firstRun: function () {
return !this.$store.getters.getSettingHOMEINIT

View File

@ -55,13 +55,12 @@
return {
server: null,
room: null,
server: null,
owner: null
}
},
computed: {
logo: function () {
return 'static/logo-small-light.png'
return 'ptweb/logo-small-light.png'
}
},
methods: {

View File

@ -1,5 +1,5 @@
<template>
<v-layout wrap row>
<v-layout wrap row ckass="pt-4">
<v-flex xs12 md8 offset-md2>
<v-card style="background: rgba(0,0,0,0.3)">
<h1 class="white--text center-text pa-1">Sign in to Plex.tv</h1>
@ -23,8 +23,8 @@
<v-flex xs12 md6 offset-md3>
<h1 class="center-text" style="color:white !important; background-color: rgba(128, 128, 128, 0.2); letter-spacing:1px">{{ pin }}</h1>
<v-layout wrap row flex class="pt-4">
<v-flex xs4 offset-xs4>
<v-btn v-clipboard="pin" light class="pt-orange">
<v-flex xs4 offset-xs4 >
<v-btn v-clipboard="pin" v-on:click.native="sendNotification()" light class="pt-orange" style="width:100%">
<v-icon light class="mr-2">content_copy</v-icon>
Copy
</v-btn>
@ -167,6 +167,9 @@
var that = this
var base64encoded = new Buffer(this.user + ":" + this.pass).toString('base64')
},
sendNotification(){
window.EventBus.$emit('notification', 'Copied to clipboard')
}
}
}

View File

@ -51,6 +51,17 @@
</v-list-tile-content>
</v-list-tile>
</v-list-item>
<v-subheader light>About</v-subheader>
<v-list-item>
<v-list-tile>
<v-list-tile-action>
<v-icon light>info</v-icon>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title>PlexTogether v{{appVersion}}</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
</v-list-item>
</v-list>
<v-dialog v-model="ptsettingstoggle">
@ -112,7 +123,10 @@
return false
}
return true
},
},
appVersion: function() {
return this.$store.state.appVersion
},
validDevices: function () {
if (!this.plex) {
return false

View File

@ -1,19 +1,8 @@
<template>
<div v-if="ptRoom" class="pl-1 pr-1" style="height:100%; overflow-x:hidden;">
<div class="hidden-md-and-up">
<v-divider light></v-divider>
<v-text-field
name="input-1"
prepend-icon="message"
:label="'Send a message to ' + '#'+ptRoom"
autoGrow
v-on:keyup.enter.native="sendMessage()"
v-model="messageToBeSent"
light
></v-text-field>
</div>
<div style="height:70%">
<v-subheader light>Users in #{{ ptRoom }} ({{ ptUsers.length }})</v-subheader>
<div v-if="ptRoom" class="pl-1 pr-1" style="height:100%; overflow-x:hidden;">
<div style="height:60%">
<h6 style="text-align:center" class="mt-3 mb-0 pb-0"> Room {{ ptRoom }}</h6>
<v-subheader light>Users ({{ ptUsers.length }})</v-subheader>
<v-list three-line dense>
<div v-for="user in ptUsers" v-bind:key="user.username" style="position:relative;height:7em">
<v-list-item style="height:4em" class="mb-0 pb-0">
@ -22,8 +11,8 @@
<img v-bind:src="user.avatarUrl"/>
</v-list-tile-avatar>
<v-list-tile-content>
<v-list-tile-title>{{ user.username }}</v-list-tile-title>
<v-list-tile-sub-title style="opacity:0.6;color:white;font-size:70%">{{getTitle(user)}}</v-list-tile-sub-title>
<v-list-tile-title> {{ user.username }}</v-list-tile-title>
<v-list-tile-sub-title style="opacity:0.6;color:white;font-size:70%"><v-icon light style="font-size:90%">{{playerState(user)}}</v-icon> - {{getTitle(user)}}</v-list-tile-sub-title>
</v-list-tile-content>
<v-list-tile-action v-if="isHost(user)">
<v-icon v-if="isHost(user)" class="pt-orange-text">star</v-icon>
@ -39,11 +28,11 @@
</div>
</v-list>
</div>
<div v-if="messages.length > 0" style="overflow-y: auto; max-height: 30%">
<div style="overflow-y: auto; height: 30%">
<v-divider light></v-divider>
<v-subheader light>Messages</v-subheader>
<div >
<v-list two-line class="pb-0 pt-0 mt-0 mb-0">
<v-list two-line class="pb-2 pt-0 mt-0 mb-2">
<v-list-item v-for="msg in messages" v-bind:key="msg">
<v-list-tile avatar tag="div">
<v-list-tile-avatar>
@ -62,18 +51,19 @@
</v-list>
</div>
</div>
<v-divider light></v-divider>
<v-text-field
class="hidden-xs-only"
style="position:absolute; bottom: 0"
name="input-1"
prepend-icon="message"
:label="'Send a message to ' + '#'+ptRoom"
autoGrow
v-on:keyup.enter.native="sendMessage()"
v-model="messageToBeSent"
light
></v-text-field>
<div style="max-height: 10%;">
<v-text-field
class="pa-1 ma-0 mt-1"
name="input-1"
prepend-icon="message"
:label="'Send a message to ' + '#'+ptRoom"
autoGrow
v-on:keyup.enter.native="sendMessage()"
v-model="messageToBeSent"
light
></v-text-field>
<v-btn style="width:100%" v-on:click.native="handleDisconnect()" class="ma-0 mt-1" primary>Leave room </v-btn>
</div>
</div>
</template>
@ -173,6 +163,9 @@
return true
}
return false
},
handleDisconnect: function () {
this.$store.dispatch('disconnectServer')
},
percent: function (user) {
let perc = (parseInt(user.time) / parseInt(user.maxTime)) * 100
@ -207,7 +200,7 @@
playerState: function (user) {
if (user.playerState) {
if (user.playerState == 'stopped') {
return 'pause'
return 'stop'
}
if (user.playerState == 'paused') {
return 'pause'
@ -216,7 +209,7 @@
return 'play_arrow'
}
}
return false
return 'stop'
},
getTimeFromMs (ms) {
var hours = ms / (1000 * 60 * 60)