component: MyAccountApplicationsComponent,
data: {
meta: {
- title: 'Applications'
+ title: $localize`Applications`
}
}
}
import { NgModule } from '@angular/core'
import { RouterModule, Routes } from '@angular/router'
import { PageNotFoundComponent } from './page-not-found.component'
-import { MetaGuard } from '@ngx-meta/core'
+import { MenuGuards } from '@app/core'
const pageNotFoundRoutes: Routes = [
{
path: '',
component: PageNotFoundComponent,
- canActivate: [ MetaGuard ],
+ canActivate: [ MenuGuards.close(true) ],
+ canDeactivate: [ MenuGuards.open(true) ],
data: {
meta: {
title: $localize`Not found`
<div class="root">
- <img src="/client/assets/images/mascot/defeated.svg" alt="404 mascot">
+ <div *ngIf="status === 404" class="box">
+ <strong>{{ status }}.</strong>
+ <span class="ml-1 text-muted" i18n>That's an error.</span>
- <div class="text" i18n>
- Sorry, we couldn't find the page you were looking for.
+ <div class="text mt-4" i18n>
+ We couldn't find any ressource tied to the URL {{ pathname }} you were looking for.
+ </div>
+
+ <div class="text-muted mt-4">
+ <span i18n="Possible reasons preceding a list of reasons a `Not Found` error page may occur">Possible reasons:</span>
+
+ <ul>
+ <li i18n>The page may have been moved or deleted</li>
+ <li i18n>You may have used an outdated or broken link</li>
+ <li i18n>You may have typed the address or URL incorrectly</li>
+ </ul>
+ </div>
+ </div>
+
+ <div *ngIf="status === 418" class="box">
+ <strong>{{ status }}.</strong>
+ <span class="ml-1 text-muted">I'm a teapot.</span>
+
+ <div class="text mt-4" i18n="Description of a tea flavour, keeping the 'requested entity body' as a technical expression referring to a web request">
+ The requested entity body blends sweet bits with a mellow earthiness.
+ </div>
+ <div class="text-muted" i18n="This is about Sepia's tea">Sepia seems to like it.</div>
</div>
+
+ <img src='/client/assets/images/mascot/{{ getMascotName() }}.svg' alt='{{ status }} mascot'>
</div>
+@import '_variables';
+@import '_mixins';
+
.root {
height: 100%;
- width: 100%;
+ margin-left: auto;
+ margin-right: auto;
text-align: center;
padding-top: 150px;
+ display: flex;
+ justify-content: center;
+ flex-direction: column-reverse;
+
+ .box {
+ text-align: left;
+ font-size: 120%;
+ padding: 0 15px;
+ }
img {
- margin-bottom: 75px;
+ margin-left: auto;
width: 220px;
height: auto;
}
- .text {
- font-size: 30px;
+ @media screen and (max-width: $mobile-view) {
+ img {
+ margin-right: auto;
+ }
+ }
+
+ @media screen and (min-width: $mobile-view) {
+ width: 400px;
+ }
+
+ @media screen and (min-width: #{breakpoint(lg)}) {
+ width: 600px;
+ }
+
+ @media screen and (min-width: #{breakpoint(xl)}) {
+ width: 700px;
+ }
+
+ @media screen and (min-width: #{breakpoint(xxl)}) {
+ width: 800px;
}
@media screen and (max-height: 600px) {
-import { Component } from '@angular/core'
+import { Component, OnInit } from '@angular/core'
+import { Title } from '@angular/platform-browser'
+import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes'
@Component({
selector: 'my-page-not-found',
templateUrl: './page-not-found.component.html',
styleUrls: [ './page-not-found.component.scss' ]
})
-export class PageNotFoundComponent {
+export class PageNotFoundComponent implements OnInit {
+ status = HttpStatusCode.NOT_FOUND_404
+ public constructor (
+ private titleService: Title
+ ) {}
+
+ ngOnInit () {
+ if (this.pathname.includes('teapot')) {
+ this.status = HttpStatusCode.I_AM_A_TEAPOT_418
+ this.titleService.setTitle($localize`I'm a teapot` + ' - PeerTube')
+ }
+ }
+
+ get pathname () {
+ return window.location.pathname
+ }
+
+ getMascotName () {
+ switch (this.status) {
+ case HttpStatusCode.I_AM_A_TEAPOT_418:
+ return 'happy'
+ case HttpStatusCode.NOT_FOUND_404:
+ default:
+ return 'defeated'
+ }
+ }
}
constructor (menu: MenuService, screen: ScreenService) { super(menu, screen, true) }
}
+@Injectable()
+export class OpenMenuAlwaysGuard extends MenuGuard {
+ constructor (menu: MenuService, screen: ScreenService) { super(menu, screen, true) }
+
+ canActivate (): boolean {
+ this.menu.setMenuDisplay(this.display)
+ return true
+ }
+}
+
@Injectable()
export class CloseMenuGuard extends MenuGuard {
constructor (menu: MenuService, screen: ScreenService) { super(menu, screen, false) }
}
+@Injectable()
+export class CloseMenuAlwaysGuard extends MenuGuard {
+ constructor (menu: MenuService, screen: ScreenService) { super(menu, screen, false) }
+
+ canActivate (): boolean {
+ this.menu.setMenuDisplay(this.display)
+ return true
+ }
+}
+
@Injectable()
export class MenuGuards {
public static guards = [
OpenMenuGuard,
- CloseMenuGuard
+ OpenMenuAlwaysGuard,
+ CloseMenuGuard,
+ CloseMenuAlwaysGuard
]
- static open () {
- return OpenMenuGuard
+ static open (always?: boolean) {
+ return always
+ ? OpenMenuAlwaysGuard
+ : OpenMenuGuard
}
- static close () {
- return CloseMenuGuard
+ static close (always?: boolean) {
+ return always
+ ? CloseMenuAlwaysGuard
+ : CloseMenuGuard
}
}
/**
* This code was defined in 1998 as one of the traditional IETF April Fools' jokes, in RFC 2324, Hyper Text Coffee Pot Control Protocol,
* and is not expected to be implemented by actual HTTP servers. The RFC specifies this code should be returned by
- * teapots requested to brew coffee. This HTTP status is used as an Easter egg in some websites, including Google.com.
+ * teapots requested to brew coffee. This HTTP status is used as an Easter egg in some websites, including PeerTube instances ;-).
*/
I_AM_A_TEAPOT_418 = 418,