diff options
7 files changed, 128 insertions, 18 deletions
diff --git a/client/src/app/+my-account/my-account-routing.module.ts b/client/src/app/+my-account/my-account-routing.module.ts index 226a4a7be..e2f8660fb 100644 --- a/client/src/app/+my-account/my-account-routing.module.ts +++ b/client/src/app/+my-account/my-account-routing.module.ts | |||
@@ -124,7 +124,7 @@ const myAccountRoutes: Routes = [ | |||
124 | component: MyAccountApplicationsComponent, | 124 | component: MyAccountApplicationsComponent, |
125 | data: { | 125 | data: { |
126 | meta: { | 126 | meta: { |
127 | title: 'Applications' | 127 | title: $localize`Applications` |
128 | } | 128 | } |
129 | } | 129 | } |
130 | } | 130 | } |
diff --git a/client/src/app/+page-not-found/page-not-found-routing.module.ts b/client/src/app/+page-not-found/page-not-found-routing.module.ts index 11399fbfd..84f400bb6 100644 --- a/client/src/app/+page-not-found/page-not-found-routing.module.ts +++ b/client/src/app/+page-not-found/page-not-found-routing.module.ts | |||
@@ -1,13 +1,14 @@ | |||
1 | import { NgModule } from '@angular/core' | 1 | import { NgModule } from '@angular/core' |
2 | import { RouterModule, Routes } from '@angular/router' | 2 | import { RouterModule, Routes } from '@angular/router' |
3 | import { PageNotFoundComponent } from './page-not-found.component' | 3 | import { PageNotFoundComponent } from './page-not-found.component' |
4 | import { MetaGuard } from '@ngx-meta/core' | 4 | import { MenuGuards } from '@app/core' |
5 | 5 | ||
6 | const pageNotFoundRoutes: Routes = [ | 6 | const pageNotFoundRoutes: Routes = [ |
7 | { | 7 | { |
8 | path: '', | 8 | path: '', |
9 | component: PageNotFoundComponent, | 9 | component: PageNotFoundComponent, |
10 | canActivate: [ MetaGuard ], | 10 | canActivate: [ MenuGuards.close(true) ], |
11 | canDeactivate: [ MenuGuards.open(true) ], | ||
11 | data: { | 12 | data: { |
12 | meta: { | 13 | meta: { |
13 | title: $localize`Not found` | 14 | title: $localize`Not found` |
diff --git a/client/src/app/+page-not-found/page-not-found.component.html b/client/src/app/+page-not-found/page-not-found.component.html index 37e382b2c..aa57b07e8 100644 --- a/client/src/app/+page-not-found/page-not-found.component.html +++ b/client/src/app/+page-not-found/page-not-found.component.html | |||
@@ -1,7 +1,32 @@ | |||
1 | <div class="root"> | 1 | <div class="root"> |
2 | <img src="/client/assets/images/mascot/defeated.svg" alt="404 mascot"> | 2 | <div *ngIf="status === 404" class="box"> |
3 | <strong>{{ status }}.</strong> | ||
4 | <span class="ml-1 text-muted" i18n>That's an error.</span> | ||
3 | 5 | ||
4 | <div class="text" i18n> | 6 | <div class="text mt-4" i18n> |
5 | Sorry, we couldn't find the page you were looking for. | 7 | We couldn't find any ressource tied to the URL {{ pathname }} you were looking for. |
8 | </div> | ||
9 | |||
10 | <div class="text-muted mt-4"> | ||
11 | <span i18n="Possible reasons preceding a list of reasons a `Not Found` error page may occur">Possible reasons:</span> | ||
12 | |||
13 | <ul> | ||
14 | <li i18n>The page may have been moved or deleted</li> | ||
15 | <li i18n>You may have used an outdated or broken link</li> | ||
16 | <li i18n>You may have typed the address or URL incorrectly</li> | ||
17 | </ul> | ||
18 | </div> | ||
19 | </div> | ||
20 | |||
21 | <div *ngIf="status === 418" class="box"> | ||
22 | <strong>{{ status }}.</strong> | ||
23 | <span class="ml-1 text-muted">I'm a teapot.</span> | ||
24 | |||
25 | <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"> | ||
26 | The requested entity body blends sweet bits with a mellow earthiness. | ||
27 | </div> | ||
28 | <div class="text-muted" i18n="This is about Sepia's tea">Sepia seems to like it.</div> | ||
6 | </div> | 29 | </div> |
30 | |||
31 | <img src='/client/assets/images/mascot/{{ getMascotName() }}.svg' alt='{{ status }} mascot'> | ||
7 | </div> | 32 | </div> |
diff --git a/client/src/app/+page-not-found/page-not-found.component.scss b/client/src/app/+page-not-found/page-not-found.component.scss index 660f4c3b8..06c1d758e 100644 --- a/client/src/app/+page-not-found/page-not-found.component.scss +++ b/client/src/app/+page-not-found/page-not-found.component.scss | |||
@@ -1,17 +1,48 @@ | |||
1 | @import '_variables'; | ||
2 | @import '_mixins'; | ||
3 | |||
1 | .root { | 4 | .root { |
2 | height: 100%; | 5 | height: 100%; |
3 | width: 100%; | 6 | margin-left: auto; |
7 | margin-right: auto; | ||
4 | text-align: center; | 8 | text-align: center; |
5 | padding-top: 150px; | 9 | padding-top: 150px; |
10 | display: flex; | ||
11 | justify-content: center; | ||
12 | flex-direction: column-reverse; | ||
13 | |||
14 | .box { | ||
15 | text-align: left; | ||
16 | font-size: 120%; | ||
17 | padding: 0 15px; | ||
18 | } | ||
6 | 19 | ||
7 | img { | 20 | img { |
8 | margin-bottom: 75px; | 21 | margin-left: auto; |
9 | width: 220px; | 22 | width: 220px; |
10 | height: auto; | 23 | height: auto; |
11 | } | 24 | } |
12 | 25 | ||
13 | .text { | 26 | @media screen and (max-width: $mobile-view) { |
14 | font-size: 30px; | 27 | img { |
28 | margin-right: auto; | ||
29 | } | ||
30 | } | ||
31 | |||
32 | @media screen and (min-width: $mobile-view) { | ||
33 | width: 400px; | ||
34 | } | ||
35 | |||
36 | @media screen and (min-width: #{breakpoint(lg)}) { | ||
37 | width: 600px; | ||
38 | } | ||
39 | |||
40 | @media screen and (min-width: #{breakpoint(xl)}) { | ||
41 | width: 700px; | ||
42 | } | ||
43 | |||
44 | @media screen and (min-width: #{breakpoint(xxl)}) { | ||
45 | width: 800px; | ||
15 | } | 46 | } |
16 | 47 | ||
17 | @media screen and (max-height: 600px) { | 48 | @media screen and (max-height: 600px) { |
diff --git a/client/src/app/+page-not-found/page-not-found.component.ts b/client/src/app/+page-not-found/page-not-found.component.ts index c91bb8649..81830d415 100644 --- a/client/src/app/+page-not-found/page-not-found.component.ts +++ b/client/src/app/+page-not-found/page-not-found.component.ts | |||
@@ -1,10 +1,37 @@ | |||
1 | import { Component } from '@angular/core' | 1 | import { Component, OnInit } from '@angular/core' |
2 | import { Title } from '@angular/platform-browser' | ||
3 | import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' | ||
2 | 4 | ||
3 | @Component({ | 5 | @Component({ |
4 | selector: 'my-page-not-found', | 6 | selector: 'my-page-not-found', |
5 | templateUrl: './page-not-found.component.html', | 7 | templateUrl: './page-not-found.component.html', |
6 | styleUrls: [ './page-not-found.component.scss' ] | 8 | styleUrls: [ './page-not-found.component.scss' ] |
7 | }) | 9 | }) |
8 | export class PageNotFoundComponent { | 10 | export class PageNotFoundComponent implements OnInit { |
11 | status = HttpStatusCode.NOT_FOUND_404 | ||
9 | 12 | ||
13 | public constructor ( | ||
14 | private titleService: Title | ||
15 | ) {} | ||
16 | |||
17 | ngOnInit () { | ||
18 | if (this.pathname.includes('teapot')) { | ||
19 | this.status = HttpStatusCode.I_AM_A_TEAPOT_418 | ||
20 | this.titleService.setTitle($localize`I'm a teapot` + ' - PeerTube') | ||
21 | } | ||
22 | } | ||
23 | |||
24 | get pathname () { | ||
25 | return window.location.pathname | ||
26 | } | ||
27 | |||
28 | getMascotName () { | ||
29 | switch (this.status) { | ||
30 | case HttpStatusCode.I_AM_A_TEAPOT_418: | ||
31 | return 'happy' | ||
32 | case HttpStatusCode.NOT_FOUND_404: | ||
33 | default: | ||
34 | return 'defeated' | ||
35 | } | ||
36 | } | ||
10 | } | 37 | } |
diff --git a/client/src/app/core/routing/menu-guard.service.ts b/client/src/app/core/routing/menu-guard.service.ts index 501e009c0..c4e64d434 100644 --- a/client/src/app/core/routing/menu-guard.service.ts +++ b/client/src/app/core/routing/menu-guard.service.ts | |||
@@ -27,22 +27,48 @@ export class OpenMenuGuard extends MenuGuard { | |||
27 | } | 27 | } |
28 | 28 | ||
29 | @Injectable() | 29 | @Injectable() |
30 | export class OpenMenuAlwaysGuard extends MenuGuard { | ||
31 | constructor (menu: MenuService, screen: ScreenService) { super(menu, screen, true) } | ||
32 | |||
33 | canActivate (): boolean { | ||
34 | this.menu.setMenuDisplay(this.display) | ||
35 | return true | ||
36 | } | ||
37 | } | ||
38 | |||
39 | @Injectable() | ||
30 | export class CloseMenuGuard extends MenuGuard { | 40 | export class CloseMenuGuard extends MenuGuard { |
31 | constructor (menu: MenuService, screen: ScreenService) { super(menu, screen, false) } | 41 | constructor (menu: MenuService, screen: ScreenService) { super(menu, screen, false) } |
32 | } | 42 | } |
33 | 43 | ||
34 | @Injectable() | 44 | @Injectable() |
45 | export class CloseMenuAlwaysGuard extends MenuGuard { | ||
46 | constructor (menu: MenuService, screen: ScreenService) { super(menu, screen, false) } | ||
47 | |||
48 | canActivate (): boolean { | ||
49 | this.menu.setMenuDisplay(this.display) | ||
50 | return true | ||
51 | } | ||
52 | } | ||
53 | |||
54 | @Injectable() | ||
35 | export class MenuGuards { | 55 | export class MenuGuards { |
36 | public static guards = [ | 56 | public static guards = [ |
37 | OpenMenuGuard, | 57 | OpenMenuGuard, |
38 | CloseMenuGuard | 58 | OpenMenuAlwaysGuard, |
59 | CloseMenuGuard, | ||
60 | CloseMenuAlwaysGuard | ||
39 | ] | 61 | ] |
40 | 62 | ||
41 | static open () { | 63 | static open (always?: boolean) { |
42 | return OpenMenuGuard | 64 | return always |
65 | ? OpenMenuAlwaysGuard | ||
66 | : OpenMenuGuard | ||
43 | } | 67 | } |
44 | 68 | ||
45 | static close () { | 69 | static close (always?: boolean) { |
46 | return CloseMenuGuard | 70 | return always |
71 | ? CloseMenuAlwaysGuard | ||
72 | : CloseMenuGuard | ||
47 | } | 73 | } |
48 | } | 74 | } |
diff --git a/shared/core-utils/miscs/http-error-codes.ts b/shared/core-utils/miscs/http-error-codes.ts index 9ba725fb9..8c8b87ba0 100644 --- a/shared/core-utils/miscs/http-error-codes.ts +++ b/shared/core-utils/miscs/http-error-codes.ts | |||
@@ -291,7 +291,7 @@ export enum HttpStatusCode { | |||
291 | /** | 291 | /** |
292 | * This code was defined in 1998 as one of the traditional IETF April Fools' jokes, in RFC 2324, Hyper Text Coffee Pot Control Protocol, | 292 | * This code was defined in 1998 as one of the traditional IETF April Fools' jokes, in RFC 2324, Hyper Text Coffee Pot Control Protocol, |
293 | * and is not expected to be implemented by actual HTTP servers. The RFC specifies this code should be returned by | 293 | * and is not expected to be implemented by actual HTTP servers. The RFC specifies this code should be returned by |
294 | * teapots requested to brew coffee. This HTTP status is used as an Easter egg in some websites, including Google.com. | 294 | * teapots requested to brew coffee. This HTTP status is used as an Easter egg in some websites, including PeerTube instances ;-). |
295 | */ | 295 | */ |
296 | I_AM_A_TEAPOT_418 = 418, | 296 | I_AM_A_TEAPOT_418 = 418, |
297 | 297 | ||