Compare commits

...

61 Commits

Author SHA1 Message Date
Simple_Not
f8e17dfcf2 cors?
Some checks failed
continuous-integration/drone/push Build is failing
2023-06-20 13:10:18 +10:00
Simple_Not
49523af734 cors?
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-20 13:05:45 +10:00
Simple_Not
5a16c641f9 fixxi fixxi
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-20 11:41:14 +10:00
ff1be13793 Position test
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-27 00:04:06 +05:00
89b8b13552 Overflow fix
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-26 23:56:54 +05:00
e8aa6b9a6c 123 2022-12-26 23:56:45 +05:00
bbb31b2729 budget dix
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-26 23:51:49 +05:00
6ecff473b3 Snow
Some checks failed
continuous-integration/drone/push Build is failing
2022-12-26 23:12:35 +05:00
782b0200e0 123
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-21 12:03:44 +05:00
275dfb6e5e thread previews remade
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-21 12:02:56 +05:00
44049bf900 Small Changes
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-17 20:57:29 +05:00
984c47c045 Tumbnail fix
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-14 20:05:29 +05:00
5aec82a819 Tumbnails added
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-13 19:45:06 +05:00
b857c1b573 Common creating component
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-13 18:21:56 +05:00
2b26ea87b6 Изменил(а) на 'docker-compose.yml'
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-09 10:24:18 -05:00
6babac8870 Изменил(а) на 'docker-compose.yml'
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-09 10:15:22 -05:00
e2cca81f81 Sdelal formochku sozdaniya treda.
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-08 01:24:35 +10:00
c17b608188 Buttons and sidebar toggle
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-04 13:01:27 +10:00
7b748f1ca2 Endpoint
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-04 04:40:10 +10:00
d0815b5772 Fixed scroll
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-04 04:39:18 +10:00
ccef7fb86f Added one button
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-04 02:40:33 +10:00
d702e01f16 Did some
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-29 22:31:55 +10:00
4f38fb65c8 Added line-break support
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-26 20:46:58 +10:00
eb577cc056 Thread now refreshes after sending the message.
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-26 20:11:02 +10:00
fb2ea59afb Small refactor.
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-25 12:36:08 +10:00
23181e4997 Endpoint fix.
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-24 14:06:34 +10:00
dae1809c5e Added threads number passing.
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-24 14:02:25 +10:00
28e0cfb239 Added threads listing.
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-24 12:54:59 +10:00
592509f337 Added guide and uploaded pictures list display.
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-21 11:09:15 +10:00
cc37c2b622 Endpoint fix
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-18 14:56:23 +10:00
57ef20f293 Redesign
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-18 14:45:51 +10:00
c4d718758b Check routerlink in post
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-12 10:31:57 +10:00
fa92bc1c5c Quick fix, set default board name.
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-12 04:06:22 +10:00
93c5826bff Support of board name parameter.
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-12 03:10:08 +10:00
85fdc0164f Added alert and textarea cleaning after send.
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-08 04:42:47 +10:00
ced76ed70c Post redesighn.
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-05 21:25:21 +10:00
0f4b8e1cb2 Post redesighn. 2022-11-05 21:24:15 +10:00
5d6360743f Изменил(а) на 'docker-compose.yml'
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-04 07:08:32 -04:00
a34220156d Изменил(а) на 'src/app/send-post/send-post.component.css'
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-03 07:31:33 -04:00
b845e21413 Изменил(а) на 'src/app/boards/post/post.component.css'
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-03 06:56:20 -04:00
9161d7c4e6 Picture Upload beta-6
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-03 20:29:16 +10:00
b1b76158c8 Picture Upload beta-5
Some checks failed
continuous-integration/drone/push Build is failing
2022-11-03 20:23:07 +10:00
550bd62ee6 Picture Upload beta-5
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-03 20:22:24 +10:00
843c9bc075 Picture Upload beta-4
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-03 15:37:24 +10:00
3cb36e2d29 Picture Upload beta-3
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-02 02:05:40 +10:00
8dc044db8c Picture Upload beta-2
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-02 02:01:34 +10:00
735ec0f76d Picture Upload beta
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-02 01:49:58 +10:00
9feb89cac0 Picture Upload beta
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-02 01:39:49 +10:00
747e93768c Some picture upload templates.
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-02 01:17:02 +10:00
2ebf25852b Merge remote-tracking branch 'origin/master'
All checks were successful
continuous-integration/drone/push Build is passing
2022-10-29 04:32:06 +10:00
21da4a4abe Merge remote-tracking branch 'origin/master' 2022-10-29 04:31:58 +10:00
049c52485f Merge remote-tracking branch 'origin/master'
All checks were successful
continuous-integration/drone/push Build is passing
2022-10-29 04:18:58 +10:00
5d93130970 added Timestamp Feature 2022-10-29 04:18:21 +10:00
cda7e38908 added textarea
All checks were successful
continuous-integration/drone/push Build is passing
2022-10-22 22:45:51 +10:00
4f8765840a posting frame
All checks were successful
continuous-integration/drone/push Build is passing
2022-10-22 22:41:06 +10:00
6c26caab00 small switch
All checks were successful
continuous-integration/drone/push Build is passing
2022-10-22 22:30:31 +10:00
Simple_Not
6e687f351e build optimizations removed removeed
All checks were successful
continuous-integration/drone/push Build is passing
2022-10-22 16:39:34 +10:00
Simple_Not
496b0a9a33 build optimizations removed
Some checks failed
continuous-integration/drone/push Build is failing
2022-10-22 16:35:12 +10:00
97baca05a7 new structire
All checks were successful
continuous-integration/drone/push Build is passing
2022-10-22 15:56:19 +10:00
c71f3e1011 new structure 2022-10-22 15:50:52 +10:00
56cbf7b140 new structure 2022-10-22 15:20:59 +10:00
67 changed files with 3336 additions and 251 deletions

1
.gitignore vendored
View File

@@ -23,6 +23,7 @@ yarn-error.log
# Visual Studio Code
.vscode
.vs
.vs/*
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json

View File

@@ -3,8 +3,7 @@
"",
"\\src",
"\\src\\app",
"\\src\\app\\about",
"\\src\\app\\boards"
"\\src\\app\\services"
],
"PreviewInSolutionExplorer": false
}

Binary file not shown.

View File

@@ -38,7 +38,7 @@
{
"type": "anyComponentStyle",
"maximumWarning": "2kb",
"maximumError": "4kb"
"maximumError": "8kb"
}
],
"fileReplacements": [
@@ -97,5 +97,8 @@
}
}
}
},
"cli": {
"analytics": false
}
}

View File

@@ -5,4 +5,10 @@ services:
container_name: ng-dvach
build: .
ports:
- "4200:4200"
- "4200:4200"
restart: always
logging:
driver: "gelf"
options:
gelf-address: "udp://graylog.vdk2ch.ru:12201"
tag: "angular-logs"

2536
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,7 @@
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve --host=0.0.0.0 --disable-host-check --verbose",
"start": "ng serve --live-reload=false --host=0.0.0.0 --disable-host-check --verbose",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "ng test"
@@ -15,10 +15,17 @@
"@angular/compiler": "^14.2.0",
"@angular/core": "^14.2.0",
"@angular/forms": "^14.2.0",
"@angular/material": "^7.0.0",
"@angular/platform-browser": "^14.2.0",
"@angular/platform-browser-dynamic": "^14.2.0",
"@angular/router": "^14.2.0",
"angular-material-sidenav": "^0.1.1",
"dotenv": "^16.0.3",
"minio": "^7.0.32",
"nestjs-minio-client": "^2.0.0",
"path": "^0.12.7",
"rxjs": "~7.5.0",
"stream": "^0.0.2",
"tslib": "^2.3.0",
"zone.js": "~0.11.4"
},
@@ -27,12 +34,14 @@
"@angular/cli": "~14.2.6",
"@angular/compiler-cli": "^14.2.0",
"@types/jasmine": "~4.0.0",
"@types/minio": "^7.0.14",
"jasmine-core": "~4.3.0",
"karma": "~6.4.0",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage": "~2.2.0",
"karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~2.0.0",
"schematics-scss-migrate": "^1.3.15",
"typescript": "~4.7.2"
}
}

View File

@@ -1,8 +0,0 @@
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class ApiChatService {
}

View File

@@ -0,0 +1,21 @@
import { NgModule } from '@angular/core';
import {RouterModule, Routes} from "@angular/router";
import {HomeComponent} from "./pages/home/home.component";
import {ThreadsComponent} from "./pages/BoardThreads/threads.component";
import {BoardsComponent} from "./pages/SingleThread/boards.component";
import {AboutComponent} from "./pages/about/about.component";
import {NotFoundComponent} from "./pages/not-found/not-found.component";
const appRoutes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'threads', component: ThreadsComponent},
{ path: 'board', component: BoardsComponent },
{ path: 'about', component: AboutComponent },
{ path: '**', component: NotFoundComponent }
]
@NgModule({
imports: [RouterModule.forRoot(appRoutes)],
exports: [RouterModule]
})
export class AppRoutingModule { }

View File

@@ -1,4 +1,70 @@
h1{
color: red;
font-size: 10rem;
.main-container {
border: 2px solid rgba(124, 124, 124, 0.5);
}
.sidenav-content {
align-items: center;
justify-content: center;
overflow: hidden;
}
.sidenav {
padding: 20px;
border: 1px solid rgba(25, 116, 211, 0.5);
}
.btn-sidebar-close{
float: right;
font-size: 45px;
font-weight: 600;
}
.navToggle-btn {
height: 40px;
color: #fff;
border-radius: 5px;
padding: 10px 25px;
font-family: 'Lato', sans-serif;
font-weight: 500;
background: transparent;
cursor: pointer;
transition: all 0.3s ease;
position: relative;
display: inline-block;
box-shadow:inset 2px 2px 2px 0px rgba(255,255,255,.5),
7px 7px 20px 0px rgba(0,0,0,.1),
4px 4px 5px 0px rgba(0,0,0,.1);
outline: none;
}
.btn-14 {
background: rgb(255,151,0);
border: none;
z-index: 1;
}
.btn-14:after {
position: absolute;
content: "";
width: 100%;
height: 0;
top: 0;
left: 0;
z-index: -1;
border-radius: 5px;
background-color: #ff0000;
background-image: linear-gradient(315deg, #000000 0%, #ff0000 74%);
box-shadow:inset 2px 2px 2px 0px rgba(255,255,255,.5);
transition: all 0.3s ease;
}
.btn-14:hover {
color: #ffffff;
}
.btn-14:hover:after {
top: auto;
bottom: 0;
height: 100%;
}
.btn-14:active {
top: 2px;
}

View File

@@ -0,0 +1,19 @@
<div>
<app-snow style="overflow: hidden;"></app-snow>
<h1>Welcome, traveler.</h1>
<mat-drawer-container class="main-container" [autosize]="true" [hasBackdrop]="false">
<mat-drawer #drawer class="sidenav" mode="side" [mode]="'push'" [opened]="true" >
<span class="btn-sidebar-close" (click)="drawer.toggle()">
&times;
</span >
<app-nav-bar></app-nav-bar>
</mat-drawer>
<div class="sidenav-content">
<button *ngIf="!drawer.opened" type="button" class = "navToggle-btn btn-14" (click)="drawer.toggle()">
Отобразить панель навигации
</button>
<br>
<router-outlet></router-outlet>
</div>
</mat-drawer-container>
</div>

View File

@@ -1,17 +1,20 @@
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `<div>
<h1>Welcome, traveler.</h1>
<nav>
<a routerLink = "">Главная </a>
<a routerLink = "about">О нас </a>
<a routerLink = "boards">Борда </a>
</nav>
<router-outlet></router-outlet>
</div>`
templateUrl: `app.component.html`,
styleUrls:['app.component.css']
})
export class AppComponent {
title = 'Nedvach Angular';
ngOnInit(): void {
}
}

View File

@@ -1,23 +1,27 @@
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { Routes, RouterModule } from '@angular/router';
import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { AboutComponent } from './about/about.component';
import { BoardsComponent } from './boards/boards.component';
import { NotFoundComponent } from './not-found/not-found.component';
import { ApiChatService } from './api-chat.service';
import { FormsModule } from '@angular/forms';
import { SendPostComponent } from './boards/send-post/send-post.component';
const appRoutes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'boards', component: BoardsComponent },
{ path: 'about', component: AboutComponent },
{ path: '**', component: NotFoundComponent },
]
import { AppComponent } from './app.component';
import { HomeComponent } from './pages/home/home.component';
import { AboutComponent } from './pages/about/about.component';
import { BoardsComponent } from './pages/SingleThread/boards.component';
import { NotFoundComponent } from './pages/not-found/not-found.component';
import { ApiChatService } from './services/api-chat.service';
import { FormsModule } from '@angular/forms';
import { PostComponent } from './pages/SingleThread/post/post.component'
import { ThreadsComponent } from './pages/BoardThreads/threads.component';
import { OPComponent } from './pages/BoardThreads/op/op.component';
import { AppRoutingModule } from './app-routing.module';
import { MatSidenavModule } from "@angular/material/sidenav";
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import { NavBarComponent } from './pages/nav-bar/nav-bar.component';
import { SendFormComponent } from './pages/send-form/send-form.component';
import { SnowComponent } from './pages/snow/snow.component';
@NgModule({
declarations: [
@@ -26,15 +30,25 @@ const appRoutes: Routes = [
AboutComponent,
BoardsComponent,
NotFoundComponent,
SendPostComponent
PostComponent,
ThreadsComponent,
OPComponent,
NavBarComponent,
SendFormComponent,
SnowComponent
],
imports: [
BrowserModule,
RouterModule.forRoot(appRoutes),
HttpClientModule,
FormsModule
FormsModule,
AppRoutingModule,
MatSidenavModule,
BrowserAnimationsModule
],
providers: [
ApiChatService
],
providers: [ApiChatService],
bootstrap: [AppComponent]
})
export class AppModule { }

View File

@@ -1,23 +0,0 @@
<div class="wrappe">
<img src="http://static.vdk2ch.ru:15555/test-public/16657431265390.png" alt="свiня" width="150">
<app-send-post></app-send-post>,
<button (click)="listPosts()">Обновить</button>
<div *ngIf="response">
<div class="singlePost" *ngFor="let post of response">
<a href="#{{post.Id}}"></a>
<img src="http://static.vdk2ch.ru:15555/test-public/оладий.jpg" alt="anonpls" width="140">
<p> >>{{post.Id}} {{post.Date}}</p>
<p>{{post.Text}}</p>
</div>
</div>
<br>
<div class="hexagon">
<div class="hexagon-inside">
<div class="hexagon-image">
</div>
</div>
</div>
</div>

View File

@@ -1,33 +0,0 @@
import { Component, OnInit } from '@angular/core';
import { ApiChatService } from '../api-chat.service';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-boards',
templateUrl: `./boards.component.html`,
styleUrls: [`./boards.component.css`]
})
export class BoardsComponent implements OnInit {
command: string = "";
response: any;
constructor(private http: HttpClient) {
console.log("Boards opened");
}
listPosts() {
console.log("Получаю данные...");
this.http.get('http://api.vdk2ch.ru:5000/List')
.subscribe((response)=> {
this.response = response;
console.log(this.response);
})
}
ngOnInit(): void {
this.listPosts();
}
}

View File

@@ -1,5 +0,0 @@
<p>
<button (click)="sendPost(textToPost.value)">Отправить</button>
</p>
<input type="text" size="80" value="Печатать сюда" #textToPost>
<p></p>

View File

@@ -1,34 +0,0 @@
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-send-post',
templateUrl: './send-post.component.html',
styleUrls: ['./send-post.component.css']
})
export class SendPostComponent implements OnInit {
constructor(private http: HttpClient) {
console.log("Открыто окно постинга");
}
sendPost(text: string) {
console.log("Отправляю пост...");
var postToSend =
{
Date: Date,
Id: 0,
Text: text
}
this.http.post('http://api.vdk2ch.ru:5000/PostTo', postToSend).subscribe();
}
ngOnInit(): void {
}
}

20
src/app/const/alert.ts Normal file
View File

@@ -0,0 +1,20 @@
const ALERT_SHOW_TIME = 5000;
const showAlert = (message:string, color:string) => {
const alertContainer = document.createElement('div');
alertContainer.style.zIndex = '100';
alertContainer.style.position = 'fixed';
alertContainer.style.left = '50';
alertContainer.style.top = '0';
alertContainer.style.right = '0';
alertContainer.style.padding = '30px 3px';
alertContainer.style.fontSize = '20px';
alertContainer.style.textAlign = 'right';
alertContainer.style.backgroundColor = color;
alertContainer.style.border = "2px dashed #6CFFDD"
alertContainer.textContent = message;
document.body.append(alertContainer);
setTimeout(() => {
alertContainer.remove();
}, ALERT_SHOW_TIME);
}
export {showAlert}

3
src/app/const/api.ts Normal file
View File

@@ -0,0 +1,3 @@
//export const api_endpoint: string = 'http://api.vdk2ch.ru:5000/';
export const api_endpoint: string = 'https://api.vdk2ch.ru/';
//export const api_endpoint: string = 'http://localhost:7141/';

View File

@@ -1 +0,0 @@
<p>home works!</p>

View File

@@ -1,17 +0,0 @@
import { Component, OnInit } from '@angular/core';
import { ApiChatService } from '../api-chat.service';
@Component({
selector: 'app-home',
template: `<img src="http://static.vdk2ch.ru:15555/test-public/sin.jpg">`
})
export class HomeComponent implements OnInit {
title = 'Home компонент';
ngOnInit(): void {
}
}

9
src/app/models/boards.ts Normal file
View File

@@ -0,0 +1,9 @@
export interface Board {
BoardName: string,
BoardExplainedName: string,
BoardID: number,
ThreadCount: number,
PostCount: number
}

View File

@@ -0,0 +1,6 @@
export interface IPicresponse {
contentType: null
serializerSettings: null
statusCode: null
value: string
}

8
src/app/models/post.ts Normal file
View File

@@ -0,0 +1,8 @@
export interface SinglePost {
Timestamp: string
Id: number
Text: string
ImgURL: string[]
Thread_Id: number
Is_OP: boolean
}

View File

@@ -1 +0,0 @@
<p>not-found works!</p>

View File

@@ -0,0 +1,21 @@
.op {
padding:20px;
width: 500px;
word-break: break-word;
word-wrap: break-word;
margin-top: 6px;
}
.preview {
border-width: 1px;
border-color: rgb(190,190,190);
border-style: solid;
background-color: #F0D0B6;
border-radius: 5px;
padding:20px;
width: 500px;
word-break: break-word;
word-wrap: break-word;
margin-top: 6px;
margin-left: 7%;
}

View File

@@ -0,0 +1,10 @@
<div class="op" [ngClass]="{op: op.Is_OP}" [ngClass]="{preview: !op.Is_OP}">
<a *ngIf="op.Thread_Id != 0" [routerLink] ="['/board']" [queryParams]="{thread: op.Thread_Id}" >Зайти в тред {{op.Thread_Id}} </a>
<p> # {{op.Id}} {{op.Timestamp}}</p>
<div>
<a *ngFor="let i of op.ImgURL" [href]="i" target="_blank">
<img [src]="setTimbnail(i)" style="height:140px">
</a>
</div>
<p>{{op.Text}}</p>
</div>

View File

@@ -1,18 +1,18 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { SendPostComponent } from './send-post.component';
import { OPComponent } from './op.component';
describe('SendPostComponent', () => {
let component: SendPostComponent;
let fixture: ComponentFixture<SendPostComponent>;
describe('OPComponent', () => {
let component: OPComponent;
let fixture: ComponentFixture<OPComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ SendPostComponent ]
declarations: [ OPComponent ]
})
.compileComponents();
fixture = TestBed.createComponent(SendPostComponent);
fixture = TestBed.createComponent(OPComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

View File

@@ -0,0 +1,22 @@
import {Component, Input, OnInit} from '@angular/core';
import { SinglePost } from '../../../models/post';
@Component({
selector: 'op-single',
templateUrl: './op.component.html',
styleUrls: ['./op.component.css']
})
export class OPComponent implements OnInit {
constructor() { }
@Input() op: SinglePost
setTimbnail(imgUrl:string){
return imgUrl.replace("thread-pics", "thread-pics-small");
}
ngOnInit(): void {
}
}

View File

@@ -0,0 +1,19 @@
<h2>Вы находитесь на доске {{boardName}} </h2>
<div>
<app-send-form [board]="boardName" (sendInfoToCreate)="createThread($event)">
</app-send-form>
</div>
<a (click)="showGuide = !showGuide" style=" font-size: small; color: chocolate; width: 500px;"> Что это и как это работает?</a>
<br>
<div *ngIf="showGuide">
Добро пожаловать в список доступных тредов. Выберите подходящий для вас тред и нажмите "войти в тред".
</div>
<br>
<button (click)="refreshOPs(boardName)">Обновить</button>
<div *ngFor="let oparrey of opsToShow">
<op-single
*ngFor="let op of oparrey" [op]="op"
></op-single>
<hr>
</div>
<button (click)="refreshOPs(boardName)">Обновить</button>

View File

@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ThreadsComponent } from './threads.component';
describe('ThreadsComponent', () => {
let component: ThreadsComponent;
let fixture: ComponentFixture<ThreadsComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ ThreadsComponent ]
})
.compileComponents();
fixture = TestBed.createComponent(ThreadsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,41 @@
import { Component, OnInit } from '@angular/core';
import { showAlert } from 'src/app/const/alert';
import {SinglePost} from "../../models/post";
import {ApiChatService} from "../../services/api-chat.service";
@Component({
selector: 'app-BoardThreads',
templateUrl: './threads.component.html',
styleUrls: ['./threads.component.css']
})
export class ThreadsComponent implements OnInit {
boardName:string = 'b'
command: string = "";
response: any;
opsToShow: SinglePost[][]
showGuide: boolean = false;
constructor(public apiChatService: ApiChatService) {
}
refreshOPs(boardName: string) {
this.apiChatService.getThreads(boardName).subscribe(response => {
this.opsToShow = response;
console.log(response);
})
}
createThread(tosend: any){
this.apiChatService.sendThreadToApi(tosend.text, tosend.images, this.boardName)
}
ngOnInit(): void {
this.apiChatService.getThreads(this.boardName).subscribe(response => {
this.opsToShow = response
})
}
}

View File

@@ -5,6 +5,7 @@
background-color: rgb(143, 142, 142);
color: #5d5d5d;
}
.wrapper {width: 800px;
margin-left: auto;
margin-right: auto;}
.wrapper {
width: 800px;
}

View File

@@ -0,0 +1,21 @@
<div class="wrapper">
<img src="http://static.vdk2ch.ru:15555/test-public/16657431265390.png" alt="свiня" width="150">
<app-send-form [board]="boardName" (sendInfoToCreate)="sendPost($event)">
</app-send-form>
<h2>Вы находитесь на доске {{boardName}} </h2>
<h3> в треде номер {{threadId}}</h3>
<a (click)="showGuide = !showGuide" style=" font-size: small; color: chocolate; width: 500px;"> Что это и как это работает?</a>
<br>
<br>
<button (click)="refreshPosts(boardName , threadId)">Обновить</button>
<post-single
*ngFor="let post of postsToShow" [post]="post"
></post-single>
<div class="hexagon">
<div class="hexagon-inside">
<div class="hexagon-image">
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,57 @@
import { Component, Input, OnInit } from '@angular/core';
import { ApiChatService } from '../../services/api-chat.service';
import { SinglePost } from '../../models/post'
import * as vars from "../../const/api"
import { showAlert } from 'src/app/const/alert';
import {ActivatedRoute} from "@angular/router";
@Component({
selector: 'app-SingleThread',
templateUrl: `./boards.component.html`,
styleUrls: [`./boards.component.css`]
})
export class BoardsComponent implements OnInit {
command: string = "";
response: any;
postsToShow: SinglePost[] = []
boardName:string = 'b';
showGuide: boolean = false;
threadId: number;
constructor(
public apiChatService: ApiChatService,
private activatedRoute:ActivatedRoute
){
}
refreshPosts(boardName: string , threadId:number) {
this.apiChatService.getPosts(boardName, this.threadId).subscribe(response => {
this.postsToShow = response
})
}
sendPost(toSend: any){
console.log(`Получен эмит создания поста с текстом ${toSend.text}`);
console.log("С картинками: " + toSend.images)
console.log("В тред " + this.threadId)
this.apiChatService.sendPostToApi(toSend.text, toSend.images, this.threadId).subscribe( response => {
response = response.toString();
showAlert(response.toString(), "#ff0a36");
this.getThreadPosts();
});
}
getThreadPosts(){
this.apiChatService.getPosts('postgres', this.threadId).subscribe(response => {
this.postsToShow = response
})
}
ngOnInit(): void {
this.threadId = parseInt(<string>this.activatedRoute.snapshot.queryParamMap.get('thread'));
this.getThreadPosts()
}
}

View File

@@ -0,0 +1,21 @@
.post {
white-space: pre-wrap;
border-width: 1px;
border-color: rgb(190,190,190);
border-style: solid;
background-color: #F0D0B6;
border-radius: 5px;
padding:20px;
width: 500px;
word-break: break-word;
word-wrap: break-word;
margin-top: 6px;
}
.postText{
}
.postPictures{
padding: 5px;
}

View File

@@ -0,0 +1,9 @@
<div class="post">
<p> # {{post.Id}} {{post.Timestamp}}</p>
<div>
<a class="postPictures" *ngFor="let i of post.ImgURL" [href]="i" target="_blank">
<img [src]="setTimbnail(i)" style="height:140px">
</a>
</div>
<p class="postText">{{post.Text}}</p>
</div>

View File

@@ -0,0 +1,24 @@
import { Component, OnInit, Input } from '@angular/core';
import { SinglePost } from '../../../models/post';
@Component({
selector: 'post-single',
templateUrl: './post.component.html',
styleUrls: [`./post.component.css`]
})
export class PostComponent implements OnInit {
@Input() post: SinglePost
setTimbnail(imgUrl:string){
return imgUrl.replace("thread-pics", "thread-pics-small");
}
ngOnInit(): void {
}
}

View File

@@ -1,6 +1,4 @@
import { Component, OnInit } from '@angular/core';
// двач лучший двач
import { ApiChatService } from '../api-chat.service';
@Component({
selector: 'app-about',
@@ -8,12 +6,9 @@ import { ApiChatService } from '../api-chat.service';
styleUrls: [`./about.component.css`]
})
export class AboutComponent implements OnInit {
// это комментарий
ngOnInit(): void {
console.log('ya tochno ne ta stroka chto budet v drugom commite!');
console.log('Yeah, you REALLY expect me to push changes without any console debugging?');
}
}

View File

@@ -0,0 +1 @@
<img src="http://static.vdk2ch.ru:15555/test-public/sin.jpg">

View File

@@ -0,0 +1,16 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-home',
templateUrl: `home.component.html`,
})
export class HomeComponent implements OnInit {
title = 'Напоминание';
ngOnInit(): void {
}
}

View File

@@ -0,0 +1,10 @@
<nav>
<a routerLink = "">Напоминание </a>
<br>
<a routerLink = "about">О нас </a>
<br>
Доски:
<div *ngFor="let board of boardsToList">
<a routerLink = "threads" title="{{board.BoardExplainedName}}">{{board.BoardName}}</a>
</div>
</nav>

View File

@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { NavBarComponent } from './nav-bar.component';
describe('NavBarComponent', () => {
let component: NavBarComponent;
let fixture: ComponentFixture<NavBarComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ NavBarComponent ]
})
.compileComponents();
fixture = TestBed.createComponent(NavBarComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,21 @@
import { Component, OnInit } from '@angular/core';
import {Board} from "../../models/boards";
import {ApiChatService} from "../../services/api-chat.service";
@Component({
selector: 'app-nav-bar',
templateUrl: './nav-bar.component.html',
styleUrls: ['./nav-bar.component.css']
})
export class NavBarComponent implements OnInit {
boardsToList: Board[];
constructor(public apiChatService: ApiChatService) {
}
ngOnInit(): void {
this.boardsToList = this.apiChatService.getBoards()
}
}

View File

@@ -0,0 +1 @@
<p>Страничка не найдена. Попробуйте внимательнее.</p>

View File

@@ -2,7 +2,8 @@ import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-not-found',
template: `<h3>Страница не найдена.<h3>`
templateUrl: './not-found.component.html',
styleUrls: ['./not-found.component.css']
})
export class NotFoundComponent implements OnInit {

View File

@@ -0,0 +1,13 @@
.posting_form {
border-width: 1px;
border-color: rgb(82, 77, 77);
border-style: solid;
background-color: #e7b58c;
border-radius: 5px;
width: 600px;
word-break: break-word;
word-wrap: break-word;
margin-left: auto;
margin-right: auto;
}

View File

@@ -0,0 +1,17 @@
<h3 *ngIf="!showForm" (click)="showForm = !showForm">Открыть форму постинга</h3>
<h3 *ngIf="showForm" (click)="showForm = !showForm" style="align-content: center">Скрыть форму постинга</h3>
<div *ngIf="showForm" class="posting_form">
<h4>Создай то, о чем будут говорить многие в /{{board}}/.</h4>
<br>
<textarea type="text" rows="8" cols="45" placeholder="Печатать сюда" #textForm [(ngModel)] = "inputText"></textarea>
<p>
<button (click)="create()" >Отправить</button>
</p>
<h1>Загрузить картинку:</h1>
<input type="file" #file placeholder="Загрузить картинку" (change)="sendPic($event)" style="display:none;">
<button type="button" class="btn btn-success" (click)="file.click()">Загрузить картинку</button>
<div *ngFor="let singlePic of inputImages" >Картинка: {{singlePic}}</div>
<p>
<button (click)="eraseData()" >Отмена</button>
</p>
</div>

View File

@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { SendFormComponent } from './send-form.component';
describe('SendFormComponent', () => {
let component: SendFormComponent;
let fixture: ComponentFixture<SendFormComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ SendFormComponent ]
})
.compileComponents();
fixture = TestBed.createComponent(SendFormComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,54 @@
import { Component, Output, EventEmitter, Input, OnInit } from '@angular/core';
import { showAlert } from 'src/app/const/alert';
import { ApiChatService } from 'src/app/services/api-chat.service';
@Component({
selector: 'app-send-form',
templateUrl: './send-form.component.html',
styleUrls: ['./send-form.component.css']
})
export class SendFormComponent implements OnInit {
@Input() board: string;
showForm:boolean = false;
inputText: string;
inputImages: string[] = [];
@Output() sendInfoToCreate = new EventEmitter();
constructor(
public apiChatService: ApiChatService) { }
create(){
var toSend = {
text: this.inputText,
images: this.inputImages
}
this.sendInfoToCreate.emit(toSend)
toSend.text = '';
toSend.images = [];
this.eraseData();
}
sendPic(event: any) {
this.apiChatService.sendpic(event.target.files[0]).subscribe(
response => {
response = response.value.toString();
this.inputImages.push(response);
showAlert(`Картинка ${response} добавлена`, "#ff0a36");
});
}
eraseData(){
this.inputImages = [];
this.inputText = '';
}
ngOnInit(): void {
}
}

View File

@@ -0,0 +1,30 @@
<div class="snow"></div>
<div class="snow"></div>
<div class="snow"></div>
<div class="snow"></div>
<div class="snow"></div>
<div class="snow"></div>
<div class="snow"></div>
<div class="snow"></div>
<div class="snow"></div>
<div class="snow"></div>
<div class="snow"></div>
<div class="snow"></div>
<div class="snow"></div>
<div class="snow"></div>
<div class="snow"></div>
<div class="snow"></div>
<div class="snow"></div>
<div class="snow"></div>
<div class="snow"></div>
<div class="snow"></div>
<div class="snow"></div>
<div class="snow"></div>
<div class="snow"></div>
<div class="snow"></div>
<div class="snow"></div>
<div class="snow"></div>
<div class="snow"></div>
<div class="snow"></div>
<div class="snow"></div>
<div class="snow"></div>

View File

@@ -0,0 +1,48 @@
@function random_range($min, $max) {
$rand: random();
$random_range: $min + floor($rand * (($max - $min) + 1));
@return $random_range;
}
.snow {
$total: 30;
position: fixed;
width: 20px;
height: 20px;
font-size: 50px;
border-radius: 50%;
pointer-events: none;
color: #f8f8f8;
z-index: 999999;
text-shadow: 1px 1px 1px #000000;
@for $i from 1 through $total {
$random-x: random(1000000) * 0.0001vw;
$random-offset: random_range(-100000, 100000) * 0.0001vw;
$random-x-end: $random-x + $random-offset;
$random-x-end-yoyo: $random-x + ($random-offset / 2);
$random-yoyo-time: random_range(30000, 80000) / 100000;
$random-yoyo-y: $random-yoyo-time * 100vh;
$random-scale: random(10000) * 0.0001;
$fall-duration: random_range(10, 30) * 1s;
$fall-delay: random(30) * -1s;
&:nth-child(#{$i}) {
opacity: random_range(2000, 8000) * 0.0001;
transform: translate($random-x, -10px) scale($random-scale);
animation: fall-#{$i} $fall-duration $fall-delay linear infinite;
}
@keyframes fall-#{$i} {
#{percentage($random-yoyo-time)} {
transform: translate($random-x-end, $random-yoyo-y) scale($random-scale);
}
to {
transform: translate($random-x-end-yoyo, 100vh) scale($random-scale);
}
}
}
}

View File

@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { SnowComponent } from './snow.component';
describe('SnowComponent', () => {
let component: SnowComponent;
let fixture: ComponentFixture<SnowComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ SnowComponent ]
})
.compileComponents();
fixture = TestBed.createComponent(SnowComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,15 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-snow',
templateUrl: './snow.component.html',
styleUrls: ['./snow.component.scss']
})
export class SnowComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}

View File

@@ -0,0 +1,73 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { SinglePost } from '../models/post';
import { Board } from "../models/boards";
import * as globals from '../const/api';
@Injectable({
providedIn: 'root'
})
export class ApiChatService {
se: any;
constructor(private http: HttpClient) {
}
getPosts(boardName: string, threadID: number): Observable<SinglePost[]> {
//console.log("Получаю посты и картинки");
return this.http.get<SinglePost[]>(globals.api_endpoint + 'List/', {params: {board: boardName, thread: threadID}});
}
sendPostToApi(text: string, imgUrl: string[], threadId: number,) {
//console.log("Отправляю пост...");
var postToSend =
{
Timestamp: "time",
Id: 0,
Text: text,
ImgURL: imgUrl,
Thread_Id: threadId
}
return this.http.post(globals.api_endpoint + 'PostTo', postToSend)
}
sendpic(picToSend: File): Observable<any> {
const PostPicture = new FormData();
PostPicture.append('PostPicture', picToSend);
return this.http.post(globals.api_endpoint + 'UploadPic', PostPicture)
}
getThreads(boardName: string): Observable<SinglePost[][]> {
//console.log("Получаю посты и картинки");
return this.http.get<SinglePost[][]>(globals.api_endpoint + 'Threads/', {params: {board: boardName}});
}
sendThreadToApi(OPtext: string, OPimgUrl: string[], board: string,){
return alert("Попытка создания тред с оп-постом " + OPtext + " на доске " + board);
}
sampleBoardList = [
{
BoardName: 'b',
BoardExplainedName: 'Всего понемногу',
BoardID: 228,
ThreadCount: 4,
PostCount: 4445
},
{
BoardName: 'vdk',
BoardExplainedName: 'Здесь живут тигры',
BoardID: 223,
ThreadCount: 1,
PostCount: 245
}
]
getBoards(): Board[] {
return this.sampleBoardList;
//return this.http.get<Board[]>(globals.api_endpoint + 'Boards/');
}
}

View File

@@ -7,7 +7,7 @@
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noPropertyAccessFromIndexSignature": false,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"sourceMap": true,
@@ -21,7 +21,8 @@
"lib": [
"es2020",
"dom"
]
],
"strictPropertyInitialization" : false
},
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,