"options": {
"baseHref": "/",
"deployUrl": "client/",
- "browserTarget": "PeerTube:build"
+ "browserTarget": "PeerTube:build",
+ "proxyConfig": "proxy.config.json"
},
"configurations": {
"production": {
"browserTarget": "PeerTube:build:hmr"
},
"e2e": {
- "browserTarget": "PeerTube:build:e2e"
+ "browserTarget": "PeerTube:build:e2e",
+ "proxyConfig": "e2e/proxy.config.json"
}
}
},
--- /dev/null
+{
+ "/api": {
+ "target": "http://localhost:9000",
+ "secure": false
+ },
+ "/plugins": {
+ "target": "http://localhost:9000",
+ "secure": false
+ },
+ "/themes": {
+ "target": "http://localhost:9000",
+ "secure": false
+ },
+ "/static": {
+ "target": "http://localhost:9000",
+ "secure": false
+ },
+ "/lazy-static": {
+ "target": "http://localhost:9000",
+ "secure": false
+ },
+ "/socket.io": {
+ "target": "ws://localhost:9000",
+ "secure": false,
+ "ws": true
+ },
+ "/!(client)**": {
+ "target": "http://localhost:3333/client/index.html",
+ "secure": false,
+ "logLevel": "debug"
+ },
+ "/!(client)**/**": {
+ "target": "http://localhost:3333/client/index.html",
+ "secure": false,
+ "logLevel": "debug"
+ }
+}
.plugin {
margin: 15px 0;
+ background-color: var(--submenuColor);
}
.first-row {
import { Hotkey, HotkeysService } from 'angular2-hotkeys'
import { I18n } from '@ngx-translate/i18n-polyfill'
import { fromEvent } from 'rxjs'
-import { ViewportScroller } from '@angular/common'
+import { PlatformLocation, ViewportScroller } from '@angular/common'
import { PluginService } from '@app/core/plugins/plugin.service'
import { HooksService } from '@app/core/plugins/hooks.service'
+import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
+import { POP_STATE_MODAL_DISMISS } from '@app/shared/misc/constants'
@Component({
selector: 'my-app',
private screenService: ScreenService,
private hotkeysService: HotkeysService,
private themeService: ThemeService,
- private hooks: HooksService
+ private hooks: HooksService,
+ private location: PlatformLocation,
+ private modalService: NgbModal
) { }
get serverVersion () {
fromEvent(window, 'resize')
.pipe(debounceTime(200))
.subscribe(() => this.onResize())
+
+ this.location.onPopState(() => this.modalService.dismissAll(POP_STATE_MODAL_DISMISS))
}
isUserLoggedIn () {
const eventsObs = this.router.events
const scrollEvent = eventsObs.pipe(filter((e: Event): e is Scroll => e instanceof Scroll))
- const navigationEndEvent = eventsObs.pipe(filter((e: Event): e is NavigationEnd => e instanceof NavigationEnd))
scrollEvent.subscribe(e => {
if (e.position) {
}
})
+ const navigationEndEvent = eventsObs.pipe(filter((e: Event): e is NavigationEnd => e instanceof NavigationEnd))
+
// When we add the a-state parameter, we don't want to alter the scroll
navigationEndEvent.pipe(pairwise())
.subscribe(([ e1, e2 ]) => {
confirm (message: string, title = '', confirmButtonText?: string) {
this.showConfirm.next({ title, message, confirmButtonText })
- return this.confirmResponse.asObservable().pipe(first()).toPromise()
+ return this.confirmResponse.asObservable()
+ .pipe(first())
+ .toPromise()
}
confirmWithInput (message: string, inputLabel: string, expectedInputValue: string, title = '', confirmButtonText?: string) {
this.showConfirm.next({ title, message, inputLabel, expectedInputValue, confirmButtonText })
- return this.confirmResponse.asObservable().pipe(first()).toPromise()
+ return this.confirmResponse.asObservable()
+ .pipe(first())
+ .toPromise()
}
}
import { I18n } from '@ngx-translate/i18n-polyfill'
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref'
+import { POP_STATE_MODAL_DISMISS } from '@app/shared/misc/constants'
@Component({
selector: 'my-confirm',
this.openedModal.result
.then(() => this.confirmService.confirmResponse.next(true))
- .catch(() => this.confirmService.confirmResponse.next(false))
+ .catch((reason: string) => {
+ // If the reason was that the user used the back button, we don't care about the confirm dialog result
+ if (!reason || reason !== POP_STATE_MODAL_DISMISS) {
+ this.confirmService.confirmResponse.next(false)
+ }
+ })
}
}
--- /dev/null
+export const POP_STATE_MODAL_DISMISS = 'pop state dismiss'
import { getStoredTheater } from '../../../assets/player/peertube-player-local-storage'
import { PluginService } from '@app/core/plugins/plugin.service'
import { HooksService } from '@app/core/plugins/hooks.service'
+import { PlatformLocation } from '@angular/common'
@Component({
selector: 'my-video-watch',
private i18n: I18n,
private hotkeysService: HotkeysService,
private hooks: HooksService,
+ private location: PlatformLocation,
@Inject(LOCALE_ID) private localeId: string
) {}
this.i18n('This video contains mature or explicit content. Are you sure you want to watch it?'),
this.i18n('Mature or explicit content')
)
- if (res === false) return this.redirectService.redirectToHomepage()
+ if (res === false) return this.location.back()
}
// Flush old player if needed
this.flushPlayer()
- // Build video element, because videojs remove it on dispose
+ // Build video element, because videojs removes it on dispose
const playerElementWrapper = this.elementRef.nativeElement.querySelector('#videojs-wrapper')
this.playerElement = document.createElement('video')
this.playerElement.className = 'video-js vjs-peertube-skin'
}
const avatar = await AvatarModel.loadByName(filename)
+ if (!avatar) return res.sendStatus(404)
+
if (avatar.onDisk === false) {
if (!avatar.fileUrl) return res.sendStatus(404)