Browse Source

Implement a talk dashboard panel

Signed-off-by: Julius Härtl <jus@bitgrid.net>
pull/3890/head
Julius Härtl 5 years ago
parent
commit
57c5bda94f
No known key found for this signature in database GPG Key ID: 4C614C6ED2CDE6DF
  1. 3
      lib/AppInfo/Application.php
  2. 70
      lib/Dashboard/TalkPanel.php
  3. 54
      src/dashboard.js
  4. 115
      src/views/Dashboard.vue
  5. 1
      webpack.common.js

3
lib/AppInfo/Application.php

@ -35,6 +35,7 @@ use OCA\Talk\Collaboration\Collaborators\Listener as CollaboratorsListener;
use OCA\Talk\Collaboration\Resources\ConversationProvider;
use OCA\Talk\Collaboration\Resources\Listener as ResourceListener;
use OCA\Talk\Config;
use OCA\Talk\Dashboard\TalkPanel;
use OCA\Talk\Events\ChatEvent;
use OCA\Talk\Events\RoomEvent;
use OCA\Talk\Files\Listener as FilesListener;
@ -95,6 +96,8 @@ class Application extends App implements IBootstrap {
$context->registerEventListener(\OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent::class, UnifiedSearchCSSLoader::class);
$context->registerSearchProvider(ConversationSearch::class);
$context->registerDashboardPanel(TalkPanel::class);
}
public function boot(IBootContext $context): void {

70
lib/Dashboard/TalkPanel.php

@ -0,0 +1,70 @@
<?php
/**
* @copyright Copyright (c) 2020 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Talk\Dashboard;
class TalkPanel implements \OCP\Dashboard\IPanel {
/**
* @inheritDoc
*/
public function getId(): string {
return 'spreed';
}
/**
* @inheritDoc
*/
public function getTitle(): string {
return 'Talk';
}
/**
* @inheritDoc
*/
public function getOrder(): int {
return 10;
}
/**
* @inheritDoc
*/
public function getIconClass(): string {
return 'icon-talk';
}
/**
* @inheritDoc
*/
public function getUrl(): ?string {
return \OC::$server->getURLGenerator()->getAbsoluteURL('/apps/spreed');
}
/**
* @inheritDoc
*/
public function load(): void {
\OC_Util::addScript('spreed', 'dashboard');
}
}

54
src/dashboard.js

@ -0,0 +1,54 @@
/*
* @copyright Copyright (c) 2020 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
import Vue from 'vue'
import { generateFilePath } from '@nextcloud/router'
import { getRequestToken } from '@nextcloud/auth'
import { translate, translatePlural } from '@nextcloud/l10n'
import Dashboard from './views/Dashboard'
// CSP config for webpack dynamic chunk loading
// eslint-disable-next-line
__webpack_nonce__ = btoa(getRequestToken())
// Correct the root of the app for chunk loading
// OC.linkTo matches the apps folders
// OC.generateUrl ensure the index.php (or not)
// We do not want the index.php since we're loading files
// eslint-disable-next-line
__webpack_public_path__ = generateFilePath('spreed', '', 'js/')
Vue.prototype.t = translate
Vue.prototype.n = translatePlural
Vue.prototype.OC = OC
Vue.prototype.OCA = OCA
document.addEventListener('DOMContentLoaded', function() {
OCA.Dashboard.register('spreed', (el) => {
const View = Vue.extend(Dashboard)
new View({
propsData: {},
}).$mount(el)
})
})

115
src/views/Dashboard.vue

@ -0,0 +1,115 @@
<!--
- @copyright Copyright (c) 2020 Julius Härtl <jus@bitgrid.net>
-
- @author Julius Härtl <jus@bitgrid.net>
-
- @license GNU AGPL version 3 or any later version
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
- published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-->
<template>
<ul v-if="roomOptions.length > 0">
<li v-for="conversation in roomOptions" :key="conversation.token">
<a :href="callLink(conversation)" class="conversation">
<ConversationIcon
:item="conversation"
:hide-favorite="false"
:hide-call="false" />
<div class="conversation__details">
<h3>{{ conversation.displayName }}</h3>
<p class="message">{{ conversation.lastMessage.message }}</p>
</div>
<button v-if="conversation.hasCall" class="primary success">{{ t('spreed', 'Join call') }}</button>
</a>
</li>
</ul>
<div v-else>
<EmptyContent icon="icon-talk">
{{ t('spreed', 'Join a conversation or start a new one') }}
<template #desc>
<p>{{ t('spreed', 'Say hi to your friends and colleagues!') }}</p>
<button>{{ t('spreed', 'Start a conversation') }}</button>
</template>
</EmptyContent>
</div>
</template>
<script>
import ConversationIcon from './../components/ConversationIcon'
import EmptyContent from '@nextcloud/vue/dist/Components/EmptyContent'
import axios from '@nextcloud/axios'
import { generateOcsUrl } from '@nextcloud/router'
export default {
name: 'Dashboard',
components: { ConversationIcon, EmptyContent },
data() {
return {
roomOptions: [],
}
},
computed: {
callLink() {
return (conversation) => {
return '/index.php/call/' + conversation.token
}
},
},
beforeMount() {
this.fetchRooms()
setInterval(() => this.fetchRooms(), 5000)
},
methods: {
fetchRooms() {
axios.get(generateOcsUrl('/apps/spreed/api/v1', 2) + 'room').then((response) => {
const rooms = response.data.ocs.data.slice(0, 6)
rooms.sort((a, b) => b.lastActivity - a.lastActivity)
this.roomOptions = rooms
})
},
},
}
</script>
<style lang="scss" scoped>
li a {
display: flex;
align-items: flex-start;
padding: 5px;
&:hover {
background-color: var(--color-background-hover);
border-radius: var(--border-radius);
}
}
.conversation__details {
padding: 3px;
overflow: hidden;
}
h3 {
font-size: 100%;
margin: 0;
}
.message {
width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
</style>

1
webpack.common.js

@ -13,6 +13,7 @@ module.exports = {
'talk-public-share-auth-sidebar': path.join(__dirname, 'src', 'mainPublicShareAuthSidebar.js'),
'talk-public-share-sidebar': path.join(__dirname, 'src', 'mainPublicShareSidebar.js'),
'flow': path.join(__dirname, 'src', 'flow.js'),
'dashboard': path.join(__dirname, 'src', 'dashboard.js'),
},
output: {
path: path.resolve(__dirname, './js'),

Loading…
Cancel
Save