Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@ module.exports = {
extends: [
'@nextcloud',
],
globals: {
// @nextcloud/webpack-vue-config globals
appName: 'readonly',
appVersion: 'readonly',
// Desktop build globals
IS_DESKTOP: 'readonly',
},
rules: {
'import/newline-after-import': 1,
'import/no-named-as-default-member': 0,
Expand Down
8 changes: 5 additions & 3 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -430,8 +430,10 @@ export default {
},

async mounted() {
// see browserCheck mixin
this.checkBrowser()
if (!IS_DESKTOP) {
// see browserCheck mixin
this.checkBrowser()
}
// Check sidebar status in previous sessions
if (BrowserStorage.getItem('sidebarOpen') === 'false') {
this.$store.dispatch('hideSidebar')
Expand Down Expand Up @@ -562,7 +564,7 @@ export default {
}
// When a conversation is opened directly, the "Talk - " part is
// missing from the title
if (this.defaultPageTitle.indexOf(t('spreed', 'Talk') + ' - ') !== 0) {
if (!IS_DESKTOP && this.defaultPageTitle.indexOf(t('spreed', 'Talk') + ' - ') !== 0) {
this.defaultPageTitle = t('spreed', 'Talk') + ' - ' + this.defaultPageTitle
}
}
Expand Down
33 changes: 33 additions & 0 deletions src/env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* @copyright Copyright (c) 2023 Grigorii Shartsev <[email protected]>
*
* @author Grigorii Shartsev <[email protected]>
*
* @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/>.
*/

declare global {
// @nextcloud/webpack-vue-config build globals
const appName: string
const appVersion: string

/**
* Build constant to divide build for web app and desktop client
*/
const IS_DESKTOP: false
}

export {}
22 changes: 12 additions & 10 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,18 @@ import 'leaflet/dist/leaflet.css'
// eslint-disable-next-line
import 'leaflet-defaulticon-compatibility'

// 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/')
if (!IS_DESKTOP) {
// 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
Expand Down
22 changes: 14 additions & 8 deletions src/mixins/sessionIssueHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,21 +48,27 @@ const sessionIssueHandler = {
SessionStorage.removeItem('joined_conversation')
// Need to delay until next tick, otherwise the PreventUnload is still being triggered
// Putting the window in front with the warning and irritating the user
this.$nextTick(() => {
// FIXME: can't use router push as it somehow doesn't clean up
// fully and leads the other instance where "Join here" was clicked
// to redirect to "not found"
window.location = url
})
if (!IS_DESKTOP) {
this.$nextTick(() => {
// FIXME: can't use router push as it somehow doesn't clean up
// fully and leads the other instance where "Join here" was clicked
// to redirect to "not found"
window.location = generateUrl(url)
})
} else {
// TODO: DESKTOP: to not hard-code the address?
window.location = `/talk_window/#${url}`
}
},

duplicateSessionTriggered() {
this.redirectTo(generateUrl('/apps/spreed/duplicate-session'))
// TODO: DESKTOP: should close the duplicated window instead of redirect
this.redirectTo('/apps/spreed/duplicate-session')
},

deletedSessionTriggered() {
// workaround: force page refresh to kill stray WebRTC connections
this.redirectTo(generateUrl('/apps/spreed/not-found'))
this.redirectTo('/apps/spreed/not-found')
},
},
}
Expand Down
30 changes: 21 additions & 9 deletions src/router/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,33 @@ import WelcomeView from '../views/WelcomeView.vue'

Vue.use(Router)

const webRootWithIndexPHP = getRootUrl() + '/index.php'
const doesURLContainIndexPHP = window.location.pathname.startsWith(webRootWithIndexPHP)
const base = generateUrl('/', {}, {
noRewrite: doesURLContainIndexPHP,
})

export default new Router({
mode: 'history',
/**
* Generate base url for Talk Web app based on server's root
*
* @return {string} Vue Router base url
*/
function generateTalkWebBasePath() {
// if index.php is in the url AND we got this far, then it's working:
// let's keep using index.php in the url
base,
const webRootWithIndexPHP = getRootUrl() + '/index.php'
const doesURLContainIndexPHP = window.location.pathname.startsWith(webRootWithIndexPHP)
return generateUrl('/', {}, {
noRewrite: doesURLContainIndexPHP,
})
}

export default new Router({
// On desktop (Electron) app is open via file:// protocol - History API is not available and no base path
mode: !IS_DESKTOP ? 'history' : 'hash',
base: !IS_DESKTOP ? generateTalkWebBasePath() : '',

linkActiveClass: 'active',

routes: [
{
path: '/apps/spreed',
// On desktop add index path as root page
alias: IS_DESKTOP ? '/' : undefined,
name: 'root',
component: WelcomeView,
props: true,
Expand Down
1 change: 1 addition & 0 deletions src/test-setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ global.OCP = {
disableKeyboardShortcuts: () => false,
},
}
global.IS_DESKTOP = false

// Work around missing "URL.createObjectURL" (which is used in the code but not
// relevant for the tests) in jsdom: https://github.com/jsdom/jsdom/issues/1721
Expand Down
14 changes: 10 additions & 4 deletions src/utils/signaling.js
Original file line number Diff line number Diff line change
Expand Up @@ -282,10 +282,16 @@ Signaling.Base.prototype.joinCall = function(token, flags, silent) {
}.bind(this))
.catch(function() {
reject(new Error())
// Server maintenance, lobby kicked in, or room not found.
// We first redirect to the conversation again and that
// will then show the proper error message to the user.
window.location = generateUrl('call/' + token)
if (!IS_DESKTOP) {
// Server maintenance, lobby kicked in, or room not found.
// We first redirect to the conversation again and that
// will then show the proper error message to the user.
window.location = generateUrl('call/' + token)
} else {
// TODO: Is it true, reload is equal to generateUrl('call/' + token) here?
// Or can we always just reload the page?
window.location.reload()
}
})
})
}
Expand Down
82 changes: 82 additions & 0 deletions webpack.common.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* @copyright Copyright (c) 2022 Grigorii Shartsev <[email protected]>
*
* @author Grigorii Shartsev <[email protected]>
*
* @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/>.
*/

const BabelLoaderExcludeNodeModulesExcept = require('babel-loader-exclude-node-modules-except')

const nextcloudWebpackRules = require('@nextcloud/webpack-vue-config/rules')

// Edit JS rule
nextcloudWebpackRules.RULE_JS.exclude = BabelLoaderExcludeNodeModulesExcept([
'@nextcloud/event-bus',
'ansi-regex',
'color.js',
'fast-xml-parser',
'hot-patcher',
'nextcloud-vue-collections',
'semver',
'strip-ansi',
'tributejs',
'vue-resize',
'webdav',
])

module.exports = {
module: {
rules: [
// Reuse @nextcloud/webpack-vue-config/rules
...Object.values(nextcloudWebpackRules),

{
/**
* webrtc-adapter main module does no longer provide
* "module.exports", which is expected by some elements using it
* (like "attachmediastream"), so it needs to be added back with
* a plugin.
*/
test: /node_modules[\\/]webrtc-adapter[\\/].*\.js$/,
loader: 'babel-loader',
options: {
plugins: ['add-module-exports'],
presets: [
/**
* From "add-module-exports" documentation:
* "webpack doesn't perform commonjs transformation for
* codesplitting. Need to set commonjs conversion."
*/
['@babel/env', { modules: 'commonjs' }],
],
},
},
{
test: /\.wasm$/i,
type: 'asset/resource',
},
{
test: /\.tflite$/i,
type: 'asset/resource',
},
{
test: /\.worker\.js$/,
use: { loader: 'worker-loader' },
},
],
},
}
Loading