Browse Source

web socket servers

master
gsd 1 year ago
parent
commit
69011ec9b2
  1. 46
      src/api/GlobalApi.js
  2. 30
      src/components/ActionDialogs/ServerStatsDialog.vue
  3. 6
      src/components/ActionDialogs/WorldwideMap.vue
  4. 12
      src/components/TabsMenuElements/ServersView/Components/ServerCard.vue
  5. 28
      src/components/TabsMenuElements/ServersView/Components/ServerFullInfo.vue
  6. 43
      src/components/TabsMenuElements/ServersView/ServersView.vue

46
src/api/GlobalApi.js

@ -19,6 +19,7 @@ export default class GlobalApi {
"e":[], "e":[],
"n":[] "n":[]
}, },
"servers_map":{},
'uniq': {"uniq":{"total":0,"month":0,"year":0,"day":0}}, 'uniq': {"uniq":{"total":0,"month":0,"year":0,"day":0}},
'builddate':0, 'builddate':0,
'ban_count':0, 'ban_count':0,
@ -41,7 +42,15 @@ export default class GlobalApi {
load_stages = new Stages(); load_stages = new Stages();
servers_ws = null;
servers_ws_first_payload = true;
constructor() { constructor() {
this.servers_ws = new WebSocket("wss://tf2.pblr-nyk.pro/ws/servers")
this.servers_ws.onopen = () => {console.log("[WS] Websocket servers connected")};
this.servers_ws.onmessage = (e) => {
this.update_server(JSON.parse(e.data)["servers"], false);
};
document.title = "Факты 13"; document.title = "Факты 13";
} }
@ -55,20 +64,16 @@ export default class GlobalApi {
} }
getHumanServerName(server) { getHumanServerName(server) {
for (const mode in this.stats['servers']) { for (const srv in this.stats.servers_map) {
for (const srv in this.stats['servers'][mode]) { if (srv['key'] === server) return srv['name'];
if (this.stats['servers'][mode][srv]['key'] === server) return this.stats['servers'][mode][srv]['name'];
}
} }
return "неизвестный"; return "неизвестный";
} }
getServers4Selector() { getServers4Selector() {
let r = []; let r = [];
for (const mode in this.stats['servers']) { for (const srv in this.stats.servers_map) {
for (const srv in this.stats['servers'][mode]) { r.push({"srv": srv['key'], "name": srv['name']})
r.push({"srv": this.stats['servers'][mode][srv]['key'], "name": this.stats['servers'][mode][srv]['name']})
}
} }
return r; return r;
} }
@ -106,6 +111,17 @@ export default class GlobalApi {
}) })
} }
update_server(response, first) {
if (first === true) {
for (let srv in response)
response[srv]['key'] = srv;
this.stats["servers_map"] = response;
} else {
for (let srv in response) {
this.stats["servers_map"][srv] = response[srv];
}
}
}
async fillServers() { async fillServers() {
this.load_stages.add("servers") this.load_stages.add("servers")
@ -113,19 +129,7 @@ export default class GlobalApi {
return axios.get("/api/stats?filter=servers" + Random.getRndWebAppend()) return axios.get("/api/stats?filter=servers" + Random.getRndWebAppend())
.then(response => response.data['servers']) .then(response => response.data['servers'])
.then(response => { .then(response => {
let srvs = { this.update_server(response, true);
'w':[],
"e":[],
'n':[]
};
for (let srv in response) {
response[srv]['key'] = srv;
if (response[srv]['status'] == false) srvs.n.push(response[srv]);
else if (response[srv]['player_count'] > 0) srvs.w.push(response[srv]);
else srvs.e.push(response[srv]);
}
srvs['w'] = srvs['w'].sort((s1,s2) => s2.player_count - s1.player_count);
this.stats['servers'] = srvs;
}) })
.catch(err => { .catch(err => {
console.log(`[API] cannot request servers, err: ${err}`); console.log(`[API] cannot request servers, err: ${err}`);

30
src/components/ActionDialogs/ServerStatsDialog.vue

@ -20,7 +20,7 @@
<p>Использование памяти: {{docker.mem.percent}}% ({{bytesToHigh(docker.mem.usage)}} / {{bytesToHigh(docker.mem.limit)}})</p> <p>Использование памяти: {{docker.mem.percent}}% ({{bytesToHigh(docker.mem.usage)}} / {{bytesToHigh(docker.mem.limit)}})</p>
<p>Всего трафика (rx/tx): {{bytesToHigh(docker.net.input)}} / {{bytesToHigh(docker.net.output)}}</p> <p>Всего трафика (rx/tx): {{bytesToHigh(docker.net.input)}} / {{bytesToHigh(docker.net.output)}}</p>
<p>Записи на диск (rx/tx): {{bytesToHigh(docker.io.input)}} / {{bytesToHigh(docker.io.output)}}</p> <p>Записи на диск (rx/tx): {{bytesToHigh(docker.io.input)}} / {{bytesToHigh(docker.io.output)}}</p>
<p>Обновленно: {{(new Date(docker.utime * 1000)).toLocaleString()}}</p> <!--<p>Обновленно: {{(new Date(docker.utime * 1000)).toLocaleString()}}</p>-->
</div> </div>
<hr width="80%"> <hr width="80%">
<div style="padding: 1% 5%; min-width: 400px; max-width: 400px"> <div style="padding: 1% 5%; min-width: 400px; max-width: 400px">
@ -42,22 +42,30 @@
<script> <script>
export default { export default {
name: "ServerStatsDialog", name: "ServerStatsDialog",
data: () => ({ props: {
show: false,
uniq: {"total":0, "month":0, "year":0, "day":0},
docker: { docker: {
"cpu":{"percent":0.0}, type: Object,
"mem":{"percent":0.0, "usage":0, "limit":0}, default: Object.create({
"io":{"input":0, "output":0}, "cpu":{"percent":0.0},
"net":{"input":0, "output":0} "mem":{"percent":0.0, "usage":0, "limit":0},
"io":{"input":0, "output":0},
"net":{"input":0, "output":0}
})
}, },
uniq: {
type: Object,
default: Object.create({"total":0, "month":0, "year":0, "day":0})
}
},
data: () => ({
show: false,
margin_bt: 'margin-bottom: 0; margin-top: 0; ' margin_bt: 'margin-bottom: 0; margin-top: 0; '
}), }),
methods: { methods: {
showMe(b, srv) { showMe(b) {
this.show = b; this.show = b;
this.uniq = srv['uniq']; //this.uniq = srv['uniq'];
this.docker = srv['dockerStats']; //this.docker = srv['dockerStats'];
}, },
bytesToHigh(bytes) { bytesToHigh(bytes) {
if (bytes < 1024) return `${(bytes).toFixed(2)} Б`; if (bytes < 1024) return `${(bytes).toFixed(2)} Б`;

6
src/components/ActionDialogs/WorldwideMap.vue

@ -3,15 +3,15 @@
<md-dialog :md-active.sync="show" @close="show=false" style="z-index: 10"> <md-dialog :md-active.sync="show" @close="show=false" style="z-index: 10">
<l-map style="height: 450px; width: 700px; border-radius: 3px; border: 3px solid #f4722b" :zoom="zoom" :center="center"> <l-map style="height: 450px; width: 700px; border-radius: 3px; border: 3px solid #f4722b" :zoom="zoom" :center="center">
<l-tile-layer :url="url" :attribution="attribution"></l-tile-layer> <l-tile-layer :url="url" :attribution="attribution"></l-tile-layer>
<l-marker v-for="srv in this.$API.stats.servers['w']" :key="srv['name']" :lat-lng="srv['city_pos']"> <l-marker v-for="srv in Object.values(this.$API.stats.servers_map).filter(server => server['player_count']>0)" :key="srv['name']" :lat-lng="srv['city_pos']">
<l-icon class-name="icom-map">{{srv['name']}}</l-icon> <l-icon class-name="icom-map">{{srv['name']}}</l-icon>
<l-popup><p class="p-map" v-on:click="$refs.wwm_ssd.openFIF(srv)">{{srv['name']}}<br>{{human_name_impl(srv['player_count'], srv['naming'])}}<br>Подключиться</p></l-popup> <l-popup><p class="p-map" v-on:click="$refs.wwm_ssd.openFIF(srv)">{{srv['name']}}<br>{{human_name_impl(srv['player_count'], srv['naming'])}}<br>Подключиться</p></l-popup>
</l-marker> </l-marker>
<l-marker v-for="srv in this.$API.stats.servers['e']" :key="srv['name']" :lat-lng="srv['city_pos']"> <l-marker v-for="srv in Object.values(this.$API.stats.servers_map).filter(server => server['player_count'] === 0 && server['status'] === true)" :key="srv['name']" :lat-lng="srv['city_pos']">
<l-icon class-name="icom-map"><div class="headline">{{srv['name']}}</div></l-icon> <l-icon class-name="icom-map"><div class="headline">{{srv['name']}}</div></l-icon>
<l-popup><p class="p-map" v-on:click="$refs.wwm_ssd.openFIF(srv)">{{srv['name']}}<br>{{human_name_impl(srv['player_count'], srv['naming'])}}<br>Подключиться</p></l-popup> <l-popup><p class="p-map" v-on:click="$refs.wwm_ssd.openFIF(srv)">{{srv['name']}}<br>{{human_name_impl(srv['player_count'], srv['naming'])}}<br>Подключиться</p></l-popup>
</l-marker> </l-marker>
<l-marker v-for="srv in this.$API.stats.servers['n']" :key="srv['name']" :lat-lng="srv['city_pos']"> <l-marker v-for="srv in Object.values(this.$API.stats.servers_map).filter(server => server['status'] === false)" :key="srv['name']" :lat-lng="srv['city_pos']">
<l-icon class-name="icom-map">{{srv['name']}}</l-icon> <l-icon class-name="icom-map">{{srv['name']}}</l-icon>
<l-popup><p class="p-map">{{srv['name']}}<br>{{human_name_impl(srv['player_count'], srv['naming'])}}</p></l-popup> <l-popup><p class="p-map">{{srv['name']}}<br>{{human_name_impl(srv['player_count'], srv['naming'])}}</p></l-popup>
</l-marker> </l-marker>

12
src/components/TabsMenuElements/ServersView/Components/ServerCard.vue

@ -3,14 +3,14 @@
<md-card> <md-card>
<md-card-media-cover md-solid> <md-card-media-cover md-solid>
<md-card-media class="card-size" md-ratio="16:9"> <md-card-media class="card-size" md-ratio="16:9">
<img :src="serverImage" :alt="serverName" crossorigin="anonymous" :style="imgIfStatus()"> <img :src="serverData['preview']" :alt="serverData['name']" crossorigin="anonymous" :style="imgIfStatus()">
</md-card-media> </md-card-media>
<md-card-area class="md-card-area-server"> <md-card-area class="md-card-area-server">
<md-card-header> <md-card-header>
<span class="md-title sc-title" style="text-align: left; font-family: tf2build; font-size: 2.5em">{{serverName}}</span> <span class="md-title sc-title" style="text-align: left; font-family: tf2build; font-size: 2.5em">{{serverData['name']}}</span>
<br class="sc-br"> <br class="sc-br">
<span class="md-subhead sc-subhead" style="text-align: left; font-family: tf2secondary; font-size: 3em">{{serverCurrentPlayer}}/{{serverMaxPlayer}}{{last_play===null?'':` | Играл: ${last_play}`}}</span> <span class="md-subhead sc-subhead" style="text-align: left; font-family: tf2secondary; font-size: 3em">{{serverData['player_count']}}/{{serverData['max_players']}}{{last_play===null?'':` | Играл: ${last_play}`}}</span>
<md-tooltip class="tooltip" md-direction="top">Нажми чтоб подключиться к {{serverName}}</md-tooltip> <md-tooltip class="tooltip" md-direction="top">Нажми чтоб подключиться к {{serverData['name']}}</md-tooltip>
</md-card-header> </md-card-header>
</md-card-area> </md-card-area>
</md-card-media-cover> </md-card-media-cover>
@ -26,10 +26,6 @@ export default {
name: 'ServerCard', name: 'ServerCard',
components: {ServerFullInfo}, components: {ServerFullInfo},
props: { props: {
serverImage: String,
serverName: String,
serverCurrentPlayer: Number,
serverMaxPlayer: Number,
serverData: { serverData: {
type: Object, type: Object,
default: null default: null

28
src/components/TabsMenuElements/ServersView/Components/ServerFullInfo.vue

@ -4,7 +4,7 @@
<div class="md-layout md-alignment-bottom-center" style="z-index: 1"> <div class="md-layout md-alignment-bottom-center" style="z-index: 1">
<div class="md-layout-item md-size-5"/> <div class="md-layout-item md-size-5"/>
<div class="md-layout-item rounded-and-colored md-size-45 md-small-size-90"> <div class="md-layout-item rounded-and-colored md-size-45 md-small-size-90">
<h3 class="txt-innert" style="text-align: center; margin: 2% 0%">{{serverInfo['name']}}</h3> <h3 class="txt-innert" style="text-align: center; margin: 2% 0%">{{serverData['name']}}</h3>
</div> </div>
<div class="md-layout-item rounded-and-colored-circle md-size-5 clickable" v-on:click="closeFIF()"> <div class="md-layout-item rounded-and-colored-circle md-size-5 clickable" v-on:click="closeFIF()">
<h3 class="txt-innert" style="text-align: center; margin: 25% 0%">X</h3> <h3 class="txt-innert" style="text-align: center; margin: 25% 0%">X</h3>
@ -12,20 +12,20 @@
</div> </div>
<div class="md-layout md-alignment-bottom-center" style="margin-top: -2.5%"> <div class="md-layout md-alignment-bottom-center" style="margin-top: -2.5%">
<div class="md-layout-item md-size-50 server-info-rounded rounded-only md-small-size-100 md-scrollbar" style="height: 660px; overflow-y: auto;"> <div class="md-layout-item md-size-50 server-info-rounded rounded-only md-small-size-100 md-scrollbar" style="height: 660px; overflow-y: auto;">
<img :src="serverInfo['preview']" style="width: 100%; height:12em;object-fit: cover;border-top-left-radius: 15px; border-top-right-radius: 15px"> <img :src="serverData['preview']" style="width: 100%; height:12em;object-fit: cover;border-top-left-radius: 15px; border-top-right-radius: 15px">
<div> <div>
<p class="p-server">{{serverInfo['description']}}</p> <p class="p-server">{{serverData['description']}}</p>
<div v-if="this.$API.player.auth('steam') === true" style="text-align: center; font-size: 0.5em !important;"> <div v-if="this.$API.player.auth('steam') === true" style="text-align: center; font-size: 0.5em !important;">
<p class="p-server clickable" style="display: inline" v-on:click="$refs.sfi_md.showMe(true, undefined, serverInfo['key'])">Чат сервера</p> <p class="p-server clickable" style="display: inline" v-on:click="$refs.sfi_md.showMe(true, undefined, serverData['key'])">Чат сервера</p>
<p class="p-server" style="display: inline"> | </p> <p class="p-server" style="display: inline"> | </p>
<p class="p-server clickable" style="display: inline" v-on:click="$refs.sfi_kdt.showMe(true, 1, serverInfo['key'])">Топ убийств</p> <p class="p-server clickable" style="display: inline" v-on:click="$refs.sfi_kdt.showMe(true, 1, serverData['key'])">Топ убийств</p>
<p class="p-server" style="display: inline"> | </p> <p class="p-server" style="display: inline"> | </p>
<p class="p-server clickable" style="display: inline" v-on:click="$refs.sfi_kdt.showMe(true, 2, serverInfo['key'])">Топ смертей</p> <p class="p-server clickable" style="display: inline" v-on:click="$refs.sfi_kdt.showMe(true, 2, serverData['key'])">Топ смертей</p>
<p class="p-server" style="display: inline"> | </p> <p class="p-server" style="display: inline"> | </p>
<p class="p-server clickable" style="display: inline" v-on:click="$refs.sfi_ssd.showMe(true, serverInfo)">Статистика</p> <p class="p-server clickable" style="display: inline" v-on:click="$refs.sfi_ssd.showMe(true, serverData)">Статистика</p>
</div> </div>
<div v-else style="text-align: center; font-size: 0.5em !important;"> <div v-else style="text-align: center; font-size: 0.5em !important;">
<p class="p-server clickable" style="display: inline" v-on:click="$refs.sfi_ssd.showMe(true, serverInfo)">Статистика сервера</p> <p class="p-server clickable" style="display: inline" v-on:click="$refs.sfi_ssd.showMe(true, serverData)">Статистика сервера</p>
</div> </div>
<hr width="30%"> <hr width="30%">
</div> </div>
@ -33,9 +33,9 @@
<div style="max-width: 40%; float: left;" v-on:click="onMove('steam')" class="clickable"> <div style="max-width: 40%; float: left;" v-on:click="onMove('steam')" class="clickable">
<TerminalSvg class="img-server"/> <TerminalSvg class="img-server"/>
<p class="p-server" style="margin-bottom: -5%">Подключиться</p> <p class="p-server" style="margin-bottom: -5%">Подключиться</p>
<p class="p-server-address">{{serverInfo['address']}}</p> <p class="p-server-address">{{serverData['address']}}</p>
</div> </div>
<div style="max-width: 40%; float: left;" v-if="serverInfo['workshop'].length > 0" v-on:click="onMove('workshop')" class="clickable"> <div style="max-width: 40%; float: left;" v-if="serverData['workshop'].length > 0" v-on:click="onMove('workshop')" class="clickable">
<SteamSvg class="img-server"/> <SteamSvg class="img-server"/>
<p class="p-server" style="margin-bottom: -5%">Workshop</p> <p class="p-server" style="margin-bottom: -5%">Workshop</p>
<p class="p-server-address">by Пельмень</p> <p class="p-server-address">by Пельмень</p>
@ -47,9 +47,9 @@
</div> </div>
</div> </div>
<hr width="30%"> <hr width="30%">
<h3 v-if="serverInfo['player_count'] < 1" style="text-align: center; line-height: 1em">На сервере пусто, заходи с друзьями...</h3> <h3 v-if="serverData['player_count'] < 1" style="text-align: center; line-height: 1em">На сервере пусто, заходи с друзьями...</h3>
<div v-else> <div v-else>
<h3 style="text-align: center" class="sfi-current-player">Сейчас играет {{serverInfo['player_count']}}/{{serverInfo['max_players']}}</h3> <h3 style="text-align: center" class="sfi-current-player">Сейчас играет {{serverData['player_count']}}/{{serverData['max_players']}}</h3>
<hr width="30%"> <hr width="30%">
<md-table v-model="players" md-sort="score" md-sort-order="desc" md-card md-fixed-header @md-selected="openPlayer" md-height="150px"> <md-table v-model="players" md-sort="score" md-sort-order="desc" md-card md-fixed-header @md-selected="openPlayer" md-height="150px">
<md-table-row slot="md-table-row" slot-scope="{ item }" md-selectable="single"> <md-table-row slot="md-table-row" slot-scope="{ item }" md-selectable="single">
@ -61,13 +61,13 @@
</md-table> </md-table>
<PlayerExtendedInfo ref="pei" :player="selected_player"/> <PlayerExtendedInfo ref="pei" :player="selected_player"/>
</div> </div>
<p class="p-server" style="text-align: center; margin: 2.5% 0;">Обновлен: {{(new Date(serverInfo['last_update']*1000)).toLocaleString()}}</p> <p class="p-server" style="text-align: center; margin: 2.5% 0;">Обновлен: {{(new Date(serverData['last_update']*1000)).toLocaleString()}}</p>
</div> </div>
</div> </div>
</md-dialog> </md-dialog>
<MessagesDialog ref="sfi_md"/> <MessagesDialog ref="sfi_md"/>
<KillDeadTop ref="sfi_kdt"/> <KillDeadTop ref="sfi_kdt"/>
<ServerStatsDialog ref="sfi_ssd"/> <ServerStatsDialog ref="sfi_ssd" :docker="serverData.dockerStats" :uniq="serverData.uniq"/>
</div> </div>
</template> </template>

43
src/components/TabsMenuElements/ServersView/ServersView.vue

@ -3,11 +3,9 @@
<div class="md-layout md-alignment-bottom-center md-small-hide" style="margin-bottom: -1%; margin-top: 1%"> <div class="md-layout md-alignment-bottom-center md-small-hide" style="margin-bottom: -1%; margin-top: 1%">
<CharacterImage :size="10" :img_src="require(`@/assets/images/characters/toilet.png`)" :audio_src="require(`@/assets/sounds/puk.mp3`)"/> <CharacterImage :size="10" :img_src="require(`@/assets/images/characters/toilet.png`)" :audio_src="require(`@/assets/sounds/puk.mp3`)"/>
</div> </div>
<div class="md-layout md-alignment-bottom-center" v-on:click="updateServers()"> <div class="md-layout md-alignment-bottom-center">
<div class="md-layout-item md-size-25 md-small-size-100 md-alignment-bottom-center rounded-and-colored clickable" style="z-index: 1"> <div class="md-layout-item md-size-25 md-small-size-100 md-alignment-bottom-center rounded-and-colored" style="z-index: 1">
<h3 class="txt-innert" style="text-align: center; margin: 4% 0%; line-height: 1em">Список серверов <h3 class="txt-innert" style="text-align: center; margin: 4% 0%; line-height: 1em">Список серверов</h3>
<md-tooltip class="tooltip" md-direction="top">Нажми чтоб обновить его</md-tooltip>
</h3>
</div> </div>
</div> </div>
<div class="md-layout md-alignment-bottom-center" style="margin-top: -1.5%"> <div class="md-layout md-alignment-bottom-center" style="margin-top: -1.5%">
@ -27,12 +25,28 @@
<h5 style="margin: 0% 0%; display: inline" class="clickable" v-on:click="$refs.sv_ssd.showMe(true)">Статистика</h5> <h5 style="margin: 0% 0%; display: inline" class="clickable" v-on:click="$refs.sv_ssd.showMe(true)">Статистика</h5>
</div> </div>
<hr> <hr>
<h5 style="text-align: center" v-if="this.$API.stats.servers['w'].length>0">где сейчас играют карлики</h5> <!---->
<ServerCard v-for="srv in this.$API.stats.servers['w']" :key="srv['name']" :server-name="srv['name']" :server-image="srv['preview']" :server-current-player="srv['player_count']" :server-max-player="srv['max_players']" :server-data="srv" :last_play="getLastPlay(srv['key'])"/> <h5 style="text-align: center" v-if="Object.values(this.$API.stats.servers_map).filter(server => server['player_count']>0).length>0">где сейчас играют карлики</h5>
<h5 style="text-align: center" v-if="this.$API.stats.servers['e'].length>0">где сейчас никого нет</h5> <ServerCard
<ServerCard v-for="srv in this.$API.stats.servers['e']" :key="srv['name']" :server-name="srv['name']" :server-image="srv['preview']" :server-current-player="srv['player_count']" :server-max-player="srv['max_players']" :server-data="srv" :last_play="getLastPlay(srv['key'])"/> v-for="srv in Object.values(this.$API.stats.servers_map).filter(server => server['player_count']>0).sort((s1, s2) => s2.player_count - s1.player_count)"
<h5 style="text-align: center" v-if="this.$API.stats.servers['n'].length>0">где сейчас играют карлики</h5> :key="srv['name']"
<ServerCard v-for="srv in this.$API.stats.servers['n']" :key="srv['name']" :server-name="srv['name']" :server-image="srv['preview']" :server-current-player="srv['player_count']" :server-max-player="srv['max_players']" :server-data="srv" :last_play="getLastPlay(srv['key'])"/> :server-data="srv"
:last_play="getLastPlay(srv['key'])"/>
<!---->
<h5 style="text-align: center" v-if="Object.values(this.$API.stats.servers_map).filter(server => server['player_count'] === 0 && server['status'] === true).length>0">где сейчас никого нет</h5>
<ServerCard
v-for="srv in Object.values(this.$API.stats.servers_map).filter(server => server['player_count'] === 0 && server['status'] === true)"
:key="srv['name']"
:server-data="srv"
:last_play="getLastPlay(srv['key'])"/>
<!---->
<h5 style="text-align: center" v-if="Object.values(this.$API.stats.servers_map).filter(server => server['status'] === false).length>0">где сейчас играют карлики</h5>
<ServerCard
v-for="srv in Object.values(this.$API.stats.servers_map).filter(server => server['status'] === false)"
:key="srv['name']"
:server-data="srv"
:last_play="getLastPlay(srv['key'])"/>
</div> </div>
</div> </div>
<SnackLoader ref="s_loader" s_text="Обновление списка серверов"/> <SnackLoader ref="s_loader" s_text="Обновление списка серверов"/>
@ -59,13 +73,6 @@ export default {
lp_cache: null lp_cache: null
}), }),
methods: { methods: {
updateServers() {
this.$refs.s_loader.setLoading(true);
this.$API.fillServers().then(() => {
this.servers = this.$API.stats.servers;
this.$refs.s_loader.setLoading(false);
})
},
getLastPlay(srv) { getLastPlay(srv) {
if (this.$API.player.store !== null) { if (this.$API.player.store !== null) {
if (this.lp_cache == null) this.lp_cache = this.$API.player.getLastplayList(this.$API.player.store); if (this.lp_cache == null) this.lp_cache = this.$API.player.getLastplayList(this.$API.player.store);

Loading…
Cancel
Save