summaryrefslogtreecommitdiff
path: root/server/controllers/chat_room.controller.ts
blob: 3917e542ac2065bae4638ae4991129af40b3a0fb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import { Body, Controller, Delete, Get, Param, Post, Put, Query } from '@nestjs/common';
import { JwtBody } from 'server/decorators/jwt_body.decorator';
import { JwtBodyDto } from 'server/dto/jwt_body.dto';
import { ChatRoomService } from 'server/providers/services/chat_room.service';
import { UsersService } from 'server/providers/services/users.service';

const haversine = (p1, p2) => {
  const degreesToRadians = (degrees) => degrees * (Math.PI / 180);
  const delta = { lat: degreesToRadians(p2.lat - p1.lat), lng: degreesToRadians(p2.lng - p1.lng) };
  const a =
    Math.sin(delta.lat / 2) * Math.sin(delta.lat / 2) +
    Math.cos(degreesToRadians(p1.lat)) *
      Math.cos(degreesToRadians(p2.lat)) *
      Math.sin(delta.lng / 2) *
      Math.sin(delta.lng / 2);
  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
  const r = 6371 * 1000;
  return r * c;
};
@Controller()
export class ChatRoomController {
  constructor(private chatRoomService: ChatRoomService, private usersService: UsersService) {}

  @Get('/chat_rooms')
  async get(@JwtBody() jwtBody: JwtBodyDto, @Query() query: any) {
    const user = await this.usersService.find(jwtBody.userId);
    const rooms = await this.chatRoomService.nearOrUserOwns({ ...query, userId: jwtBody.userId });
    return rooms.map((cr) => {
      const editable = cr.userId === user.id;
      const joinable = editable || haversine({ lat: cr.latitude, lng: cr.longitude }, query) <= cr.radius;
      return joinable
        ? { ...cr, editable, joinable }
        : {
            name: cr.name,
            latitude: cr.latitude,
            longitude: cr.longitude,
            radius: cr.radius,
            editable,
            joinable,
          };
    });
  }

  @Get('/chat_rooms/:id')
  async getId(@Param('id') id: string) {
    return await this.chatRoomService.findById(id);
  }

  @Get('/chat_rooms/:id/joinable')
  async joinable(@JwtBody() jwtBody: JwtBodyDto, @Param('id') id: string, @Query() query: any) {
    return !!(await this.chatRoomService.nearOrUserOwns({ ...query, userId: jwtBody.userId })).find(
      (cr) =>
        cr.id == id &&
        (haversine({ lat: cr.latitude, lng: cr.longitude }, query) <= cr.radius || cr.userId === jwtBody.userId),
    );
  }

  @Post('/chat_rooms')
  async create(@JwtBody() jwtBody: JwtBodyDto, @Body() chatRoom: any) {
    chatRoom.user = await this.usersService.find(jwtBody.userId);
    return await this.chatRoomService.create(chatRoom);
  }

  private async userCanEdit(jwtBody: JwtBodyDto, chatRoom: any) {
    const user = await this.usersService.find(jwtBody.userId);
    if (user.id !== chatRoom.user.id) {
      return {
        error: 'You are not the owner of this chat room',
      };
    }
    return true;
  }

  @Put('/chat_rooms/:id')
  async update(@JwtBody() jwtBody: JwtBodyDto, @Param('id') id: string, @Body() chatRoom: any) {
    console.log(id);
    const chat_room = await this.chatRoomService.findById(id, ['user']);
    if (!(await this.userCanEdit(jwtBody, chat_room))) {
      return chat_room;
    }
    chat_room.latitude = chatRoom.latitude;
    chat_room.longitude = chatRoom.longitude;
    chat_room.radius = chatRoom.radius;
    return await this.chatRoomService.save(chat_room);
  }

  @Delete('/chat_rooms/:id')
  async delete(@JwtBody() jwtBody: JwtBodyDto, @Param('id') id: string) {
    const chat_room = await this.chatRoomService.findById(id, ['user']);
    if (!(await this.userCanEdit(jwtBody, chat_room))) {
      return false;
    }
    return await this.chatRoomService.remove(chat_room);
  }
}