material theming
This commit is contained in:
parent
cdfa1da90a
commit
bdc86eb26c
@ -32,7 +32,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"styles": [
|
"styles": [
|
||||||
"@angular/material/prebuilt-themes/azure-blue.css",
|
|
||||||
"node_modules/ngx-toastr/toastr.css",
|
"node_modules/ngx-toastr/toastr.css",
|
||||||
"src/styles.scss"
|
"src/styles.scss"
|
||||||
],
|
],
|
||||||
@ -40,6 +39,12 @@
|
|||||||
},
|
},
|
||||||
"configurations": {
|
"configurations": {
|
||||||
"production": {
|
"production": {
|
||||||
|
"fileReplacements": [
|
||||||
|
{
|
||||||
|
"replace": "src/environment/environment.ts",
|
||||||
|
"with": "src/environment/environment.prod.ts"
|
||||||
|
}
|
||||||
|
],
|
||||||
"budgets": [
|
"budgets": [
|
||||||
{
|
{
|
||||||
"type": "initial",
|
"type": "initial",
|
||||||
@ -93,7 +98,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"styles": [
|
"styles": [
|
||||||
"@angular/material/prebuilt-themes/cyan-orange.css",
|
|
||||||
"src/styles.scss"
|
"src/styles.scss"
|
||||||
],
|
],
|
||||||
"scripts": []
|
"scripts": []
|
||||||
|
@ -38,4 +38,4 @@
|
|||||||
"karma-jasmine-html-reporter": "~2.1.0",
|
"karma-jasmine-html-reporter": "~2.1.0",
|
||||||
"typescript": "~5.7.2"
|
"typescript": "~5.7.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1 +0,0 @@
|
|||||||
<router-outlet />
|
|
@ -4,9 +4,6 @@ import { RouterOutlet } from '@angular/router';
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
imports: [RouterOutlet],
|
imports: [RouterOutlet],
|
||||||
templateUrl: './app.component.html',
|
template: "<router-outlet />",
|
||||||
styleUrl: './app.component.scss'
|
|
||||||
})
|
})
|
||||||
export class AppComponent {
|
export class AppComponent { }
|
||||||
|
|
||||||
}
|
|
||||||
|
@ -10,6 +10,8 @@ import { MessageComponent } from './chat/feed/message/message.component';
|
|||||||
import { ProfilePictureComponent } from './chat/feed/message/profile-picture/profile-picture.component';
|
import { ProfilePictureComponent } from './chat/feed/message/profile-picture/profile-picture.component';
|
||||||
import { ToolbarComponent } from '../common/toolbar/toolbar.component';
|
import { ToolbarComponent } from '../common/toolbar/toolbar.component';
|
||||||
import { MatBadgeModule } from '@angular/material/badge';
|
import { MatBadgeModule } from '@angular/material/badge';
|
||||||
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
@ -24,7 +26,9 @@ import { MatBadgeModule } from '@angular/material/badge';
|
|||||||
CommonModule,
|
CommonModule,
|
||||||
ChatRoutingModule,
|
ChatRoutingModule,
|
||||||
ToolbarComponent,
|
ToolbarComponent,
|
||||||
MatBadgeModule
|
MatBadgeModule,
|
||||||
|
MatButtonModule,
|
||||||
|
MatTooltipModule
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class ChatModule { }
|
export class ChatModule { }
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
<div [title]="channel.description" [class.selected]="selected">
|
<div>
|
||||||
|
<button
|
||||||
<span [matBadge]="this.hasAlert ? '1' : ''" matBadgeSize="small">
|
mat-stroked-button
|
||||||
{{channel.name}}
|
[matTooltip]="channel.description"
|
||||||
</span>
|
matTooltipPosition="right"
|
||||||
|
[matBadge]="this.hasAlert ? '1' : ''"
|
||||||
|
matBadgeSize="medium"
|
||||||
|
[disabled]="this.selected">
|
||||||
|
{{channel.name}}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,10 +1,5 @@
|
|||||||
div {
|
button {
|
||||||
padding: 5px 10px;
|
width: 70%;
|
||||||
cursor: pointer;
|
display: block;
|
||||||
}
|
margin: 10px auto;
|
||||||
|
|
||||||
.selected {
|
|
||||||
color: var(--mat-sys-on-secondary);
|
|
||||||
background: linear-gradient(to right, var(--mat-sys-secondary), var(--mat-sys-secondary-container) 90%, rgba(0,0,0,0));
|
|
||||||
transition: all .3s ease-in-out;
|
|
||||||
}
|
}
|
@ -1,4 +1,3 @@
|
|||||||
:host {
|
:host {
|
||||||
color: var(--mat-sys-on-surface);
|
background-color: var(--mat-sys-surface-container);
|
||||||
background-color: var(--mat-sys-surface);
|
|
||||||
}
|
}
|
@ -1,5 +1,5 @@
|
|||||||
#container {
|
#container {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: minmax(auto, 200px) 1fr;
|
grid-template-columns: minmax(auto, 150px) 1fr;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
@ -1,8 +1,7 @@
|
|||||||
:host {
|
:host {
|
||||||
color: var(--mat-sys-on-background);
|
border-left: 2px solid var(--mat-sys-surface-variant);
|
||||||
background-color: var(--mat-sys-background);
|
border-top: 2px solid var(--mat-sys-surface-variant);
|
||||||
|
|
||||||
border-left: 2px solid var(--mat-sys-secondary);
|
|
||||||
border-top: 2px solid var(--mat-sys-secondary);
|
|
||||||
border-radius: 10px 0;
|
border-radius: 10px 0;
|
||||||
|
|
||||||
|
background-color: var(--mat-sys-background);
|
||||||
}
|
}
|
@ -3,6 +3,7 @@ import { Message } from '../../../models/message';
|
|||||||
import { ChatService } from '../../../services/chat.service';
|
import { ChatService } from '../../../services/chat.service';
|
||||||
import { UserService } from '../../../services/user.service';
|
import { UserService } from '../../../services/user.service';
|
||||||
import { Channel } from '../../../models/channel';
|
import { Channel } from '../../../models/channel';
|
||||||
|
import { Subscription } from 'rxjs';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-feed',
|
selector: 'app-feed',
|
||||||
@ -14,14 +15,20 @@ export class FeedComponent implements OnChanges {
|
|||||||
private readonly DEFAULT_CHANNEL_ID: number = 1;
|
private readonly DEFAULT_CHANNEL_ID: number = 1;
|
||||||
|
|
||||||
@Input('channel') public channel?: Channel;
|
@Input('channel') public channel?: Channel;
|
||||||
public messages!: Message[];
|
public messages: Message[] = [];
|
||||||
|
|
||||||
|
public subscription?: Subscription;
|
||||||
|
|
||||||
constructor(private chatService: ChatService, private userService: UserService) { }
|
constructor(private chatService: ChatService, private userService: UserService) { }
|
||||||
|
|
||||||
ngOnChanges() {
|
ngOnChanges() {
|
||||||
this.chatService.GetMessages(this.channel?.id ?? this.DEFAULT_CHANNEL_ID)
|
if (this.subscription) {
|
||||||
.subscribe(messages => {
|
this.subscription.unsubscribe();
|
||||||
this.messages = messages;
|
this.messages = [];
|
||||||
});
|
}
|
||||||
|
|
||||||
|
this.subscription =
|
||||||
|
this.chatService.GetMessages(this.channel?.id ?? this.DEFAULT_CHANNEL_ID)
|
||||||
|
.subscribe(message => this.messages.push(message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,5 +3,5 @@ img {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
box-shadow: 0px 0px 5px rgba(0, 0, 0, 1);
|
box-shadow: 0px 0px 5px var(--mat-sys-on-background);
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
import { Component, Input, OnInit } from '@angular/core';
|
import { Component, Input, OnInit } from '@angular/core';
|
||||||
import { UserService } from '../../../../../services/user.service';
|
import { UserService } from '../../../../../services/user.service';
|
||||||
|
import { ToastrService } from 'ngx-toastr';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-profile-picture',
|
selector: 'app-profile-picture',
|
||||||
@ -11,10 +12,15 @@ export class ProfilePictureComponent implements OnInit {
|
|||||||
@Input("username") public username!: string;
|
@Input("username") public username!: string;
|
||||||
public url?: string;
|
public url?: string;
|
||||||
|
|
||||||
constructor(private userService: UserService) { }
|
constructor(private userService: UserService, private toastrService: ToastrService) { }
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.userService.GetProfilePictureURL(this.username)
|
this.userService.GetProfilePictureURL(this.username)
|
||||||
.subscribe(url => this.url = url);
|
.subscribe({
|
||||||
|
next: url => this.url = url,
|
||||||
|
error: _ => {
|
||||||
|
this.toastrService.error("failed to fetch user info", "Error")
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
mat-toolbar {
|
||||||
|
background-color: var(--mat-sys-surface-container);
|
||||||
|
}
|
||||||
|
|
||||||
.toolbar-right-side {
|
.toolbar-right-side {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
|
@ -3,13 +3,12 @@ import { inject, Injectable } from '@angular/core';
|
|||||||
import { catchError, map, Observable, of } from 'rxjs';
|
import { catchError, map, Observable, of } from 'rxjs';
|
||||||
import { LoginResponse, RegisterResponse } from './responses/auth';
|
import { LoginResponse, RegisterResponse } from './responses/auth';
|
||||||
import { ActivatedRouteSnapshot, CanActivateFn, Router, RouterStateSnapshot } from '@angular/router';
|
import { ActivatedRouteSnapshot, CanActivateFn, Router, RouterStateSnapshot } from '@angular/router';
|
||||||
|
import { environment } from '../../environment/environment';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
})
|
})
|
||||||
export class AuthService {
|
export class AuthService {
|
||||||
private readonly API_BASE: string = "http://localhost:5000"
|
|
||||||
|
|
||||||
private readonly SESSION_COOKIE: string = "session";
|
private readonly SESSION_COOKIE: string = "session";
|
||||||
private readonly USERNAME_FIELD: string = "username";
|
private readonly USERNAME_FIELD: string = "username";
|
||||||
private readonly PASSWORD_FIELD: string = "password";
|
private readonly PASSWORD_FIELD: string = "password";
|
||||||
@ -18,7 +17,7 @@ export class AuthService {
|
|||||||
constructor(private http: HttpClient) { }
|
constructor(private http: HttpClient) { }
|
||||||
|
|
||||||
public Login(username: string, password: string): Observable<LoginResponse> {
|
public Login(username: string, password: string): Observable<LoginResponse> {
|
||||||
let url = `${this.API_BASE}/auth/login`;
|
let url = `${environment.apiBase}/auth/login`;
|
||||||
|
|
||||||
let formData = new FormData();
|
let formData = new FormData();
|
||||||
formData.append(this.USERNAME_FIELD, username);
|
formData.append(this.USERNAME_FIELD, username);
|
||||||
@ -28,7 +27,7 @@ export class AuthService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Register(username: string, password: string, repeatPassword: string): Observable<RegisterResponse> {
|
public Register(username: string, password: string, repeatPassword: string): Observable<RegisterResponse> {
|
||||||
let url = `${this.API_BASE}/auth/register`;
|
let url = `${environment.apiBase}/auth/register`;
|
||||||
|
|
||||||
let formData = new FormData();
|
let formData = new FormData();
|
||||||
formData.append(this.USERNAME_FIELD, username);
|
formData.append(this.USERNAME_FIELD, username);
|
||||||
@ -39,7 +38,7 @@ export class AuthService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Logout(): Observable<boolean> {
|
public Logout(): Observable<boolean> {
|
||||||
let url = `${this.API_BASE}/auth/logout`;
|
let url = `${environment.apiBase}/auth/logout`;
|
||||||
|
|
||||||
return this.http.get(url, { withCredentials: true }).pipe(
|
return this.http.get(url, { withCredentials: true }).pipe(
|
||||||
map(() => true),
|
map(() => true),
|
||||||
@ -48,7 +47,7 @@ export class AuthService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Bump(): Observable<boolean> {
|
public Bump(): Observable<boolean> {
|
||||||
let url = `${this.API_BASE}/auth/bump`
|
let url = `${environment.apiBase}/auth/bump`
|
||||||
|
|
||||||
return this.http.get(url, { withCredentials: true }).pipe(
|
return this.http.get(url, { withCredentials: true }).pipe(
|
||||||
map(() => true),
|
map(() => true),
|
||||||
@ -68,8 +67,8 @@ export class AuthService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const IsLoggedInCanActivate: CanActivateFn = (
|
export const IsLoggedInCanActivate: CanActivateFn = (
|
||||||
route: ActivatedRouteSnapshot,
|
_: ActivatedRouteSnapshot,
|
||||||
state: RouterStateSnapshot
|
__: RouterStateSnapshot
|
||||||
) => {
|
) => {
|
||||||
if (inject(AuthService).IsLoggedIn()) {
|
if (inject(AuthService).IsLoggedIn()) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { Observable } from 'rxjs';
|
import { from, Observable } from 'rxjs';
|
||||||
import { Channel } from '../models/channel';
|
import { Channel } from '../models/channel';
|
||||||
import { Message } from '../models/message';
|
import { Message } from '../models/message';
|
||||||
|
|
||||||
@ -21,7 +21,7 @@ export class ChatService {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
name: 'gaming',
|
name: 'XIV. Leo',
|
||||||
description: 'this is another channel'
|
description: 'this is another channel'
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
@ -32,25 +32,142 @@ export class ChatService {
|
|||||||
// TODO: implement
|
// TODO: implement
|
||||||
// TODO: refactor this so it first returns the n last messages,
|
// TODO: refactor this so it first returns the n last messages,
|
||||||
// then listens for incoming messages and forwards them as they come
|
// then listens for incoming messages and forwards them as they come
|
||||||
public GetMessages(channelID: number): Observable<Message[]> {
|
public GetMessages(channelID: number): Observable<Message> {
|
||||||
return new Observable<Message[]>(subscriber => {
|
|
||||||
subscriber.next([
|
return from([
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
sender: 'Test User 1',
|
sender: 'admin',
|
||||||
channel: 1,
|
channel: 1,
|
||||||
time: new Date(),
|
time: new Date(),
|
||||||
content: 'this is my first message'
|
content: 'this is my first message'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 2,
|
id: 1,
|
||||||
sender: 'Test User 2',
|
sender: 'admin',
|
||||||
channel: 2,
|
channel: 1,
|
||||||
time: new Date(),
|
time: new Date(),
|
||||||
content: 'this is my second message'
|
content: 'this is my first message'
|
||||||
}
|
},
|
||||||
]);
|
{
|
||||||
subscriber.complete();
|
id: 1,
|
||||||
});
|
sender: 'admin',
|
||||||
|
channel: 1,
|
||||||
|
time: new Date(),
|
||||||
|
content: 'this is my first message'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
sender: 'admin',
|
||||||
|
channel: 1,
|
||||||
|
time: new Date(),
|
||||||
|
content: 'this is my first message'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
sender: 'admin',
|
||||||
|
channel: 1,
|
||||||
|
time: new Date(),
|
||||||
|
content: 'this is my first message'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
sender: 'admin',
|
||||||
|
channel: 1,
|
||||||
|
time: new Date(),
|
||||||
|
content: 'this is my first message'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
sender: 'admin',
|
||||||
|
channel: 1,
|
||||||
|
time: new Date(),
|
||||||
|
content: 'this is my first message'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
sender: 'admin',
|
||||||
|
channel: 1,
|
||||||
|
time: new Date(),
|
||||||
|
content: 'this is my first message'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
sender: 'admin',
|
||||||
|
channel: 1,
|
||||||
|
time: new Date(),
|
||||||
|
content: 'this is my first message'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
sender: 'admin',
|
||||||
|
channel: 1,
|
||||||
|
time: new Date(),
|
||||||
|
content: 'this is my first message'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
sender: 'admin',
|
||||||
|
channel: 1,
|
||||||
|
time: new Date(),
|
||||||
|
content: 'this is my first message'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
sender: 'admin',
|
||||||
|
channel: 1,
|
||||||
|
time: new Date(),
|
||||||
|
content: 'this is my first message'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
sender: 'admin',
|
||||||
|
channel: 1,
|
||||||
|
time: new Date(),
|
||||||
|
content: 'this is my first message'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
sender: 'admin',
|
||||||
|
channel: 1,
|
||||||
|
time: new Date(),
|
||||||
|
content: 'this is my first message'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
sender: 'admin',
|
||||||
|
channel: 1,
|
||||||
|
time: new Date(),
|
||||||
|
content: 'this is my first message'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
sender: 'admin',
|
||||||
|
channel: 1,
|
||||||
|
time: new Date(),
|
||||||
|
content: 'this is my first message'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
sender: 'admin',
|
||||||
|
channel: 1,
|
||||||
|
time: new Date(),
|
||||||
|
content: 'this is my first message'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
sender: 'admin',
|
||||||
|
channel: 1,
|
||||||
|
time: new Date(),
|
||||||
|
content: 'this is my first message'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
sender: 'admin',
|
||||||
|
channel: 2,
|
||||||
|
time: new Date(),
|
||||||
|
content: 'this is my second message'
|
||||||
|
}
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
6
src/app/services/responses/user.ts
Normal file
6
src/app/services/responses/user.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import { User } from "../../models/user";
|
||||||
|
import { APIResponse } from "./basic";
|
||||||
|
|
||||||
|
export class UserInfoResponse extends APIResponse {
|
||||||
|
public user?: User;
|
||||||
|
}
|
@ -1,23 +1,52 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { Observable } from 'rxjs';
|
import { catchError, map, Observable, throwError } from 'rxjs';
|
||||||
import { User } from '../models/user';
|
import { User } from '../models/user';
|
||||||
|
import { HttpClient } from '@angular/common/http';
|
||||||
|
import { UserInfoResponse } from './responses/user';
|
||||||
|
import { environment } from '../../environment/environment';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
})
|
})
|
||||||
export class UserService {
|
export class UserService {
|
||||||
constructor() { }
|
private users: Map<string, User> = new Map<string, User>();
|
||||||
|
|
||||||
// TODO: implement
|
constructor(private http: HttpClient) { }
|
||||||
public GetProfilePictureURL(username: string): Observable<string> {
|
|
||||||
return new Observable<string>(subscriber => {
|
public GetUser(username: string): Observable<User> {
|
||||||
subscriber.next("https://i.pinimg.com/736x/00/70/16/00701602b0eac0390b3107b9e2a665e0.jpg");
|
if (this.users.has(username)) {
|
||||||
subscriber.complete();
|
return new Observable<User>(subscriber => {
|
||||||
});
|
subscriber.next(this.users.get(username)!);
|
||||||
|
subscriber.complete();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
let url = `${environment.apiBase}/user/info/${username}`
|
||||||
|
return this.http.get<UserInfoResponse>(url, { withCredentials: true }).pipe(
|
||||||
|
map(response => {
|
||||||
|
if (response.error) {
|
||||||
|
throw new Error(response.error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.user) {
|
||||||
|
this.users.set(username, response.user);
|
||||||
|
return response.user;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error("bad API response, missing user with no error");
|
||||||
|
}),
|
||||||
|
catchError(error => throwError(() => new Error(error.error.message)))
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: implement
|
public GetProfilePictureURL(username: string): Observable<string> {
|
||||||
public GetUser(username: string): Observable<User> {
|
if (this.users.has(username)) {
|
||||||
throw new Error('Not implemented');
|
return new Observable<string>(subscriber => {
|
||||||
|
subscriber.next(this.users.get(username)!.picture);
|
||||||
|
subscriber.complete();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return this.GetUser(username).pipe(map(user => user.picture));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
4
src/environment/environment.prod.ts
Normal file
4
src/environment/environment.prod.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export const environment = {
|
||||||
|
production: true,
|
||||||
|
apiBase: "https://chat.tek.govt.hu/api"
|
||||||
|
}
|
4
src/environment/environment.ts
Normal file
4
src/environment/environment.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export const environment = {
|
||||||
|
production: false,
|
||||||
|
apiBase: "http://localhost:5000"
|
||||||
|
}
|
@ -2,7 +2,7 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Ui</title>
|
<title>Chat</title>
|
||||||
<base href="/">
|
<base href="/">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||||
|
@ -1,4 +1,24 @@
|
|||||||
/* You can add global styles to this file, and also import other style files */
|
@use '@angular/material' as mat;
|
||||||
|
|
||||||
html, body { height: 100%; }
|
html,
|
||||||
body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
|
body {
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
font-family: var(--mat-sys-body-medium-font);
|
||||||
|
background-color: var(--mat-sys-surface-container);
|
||||||
|
|
||||||
|
color-scheme: light dark;
|
||||||
|
@include mat.theme((
|
||||||
|
color: mat.$azure-palette,
|
||||||
|
typography: Roboto,
|
||||||
|
density: 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
.force-light-mode {
|
||||||
|
color-scheme: light !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.force-dark-mode {
|
||||||
|
color-scheme: dark !important;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user