Skip to content

Commit

Permalink
add show online/offline user
Browse files Browse the repository at this point in the history
  • Loading branch information
Impeqq committed Nov 16, 2021
1 parent c5ad851 commit 23e3ff2
Show file tree
Hide file tree
Showing 25 changed files with 379 additions and 38 deletions.
2 changes: 2 additions & 0 deletions backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@
"@nestjs/core": "^7.5.1",
"@nestjs/graphql": "^7.9.1",
"@nestjs/platform-express": "^7.5.1",
"@nestjs/platform-socket.io": "^8.2.0",
"@nestjs/typeorm": "^7.1.5",
"@nestjs/websockets": "^8.2.0",
"apollo-server-express": "^2.19.0",
"bcryptjs": "^2.4.3",
"graphql": "^15.4.0",
Expand Down
2 changes: 0 additions & 2 deletions backend/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import { join } from 'path';
import { UserModule } from './user/user.module';
import { MessageModule } from './message/message.module';
import { ChatModule } from './chat/chat.module';
import { FileController } from './file/file.controller';
import { FileService } from './file/file.service';
import { FileModule } from './file/file.module';

@Module({
Expand Down
7 changes: 7 additions & 0 deletions backend/src/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export interface ISubscription {
messageSent(chat_id?: string): Message | Promise<Message>;
messagesUpdated(chat_id?: string): MessageUpdates | Promise<MessageUpdates>;
userRegistred(): User | Promise<User>;
userOnline(): UserOnline | Promise<UserOnline>;
}

export interface File {
Expand Down Expand Up @@ -94,8 +95,14 @@ export interface User {
firstName: string;
lastName: string;
createdAt: string;
online?: boolean;
avatar?: File;
}

export interface UserOnline {
id?: string;
online?: boolean;
}

export type Buffer = any;
export type Upload = any;
4 changes: 4 additions & 0 deletions backend/src/user/user.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ export class UserEntity extends BaseEntity {
@Column('text')
lastName: string;

@Field()
@Column('boolean', { default: false, nullable: true })
online: boolean;

@OneToOne(() => FileEntity)
@JoinColumn()
avatar?: FileEntity;
Expand Down
39 changes: 39 additions & 0 deletions backend/src/user/user.gateway.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import {
WebSocketGateway,
OnGatewayInit,
WebSocketServer,
OnGatewayConnection,
OnGatewayDisconnect,
} from '@nestjs/websockets';
import { Logger } from '@nestjs/common';
import { Socket, Server } from 'socket.io';
import { UserService } from './user.service';
import { pubsub } from 'src/lib/pubsub';

@WebSocketGateway(5001, { cors: true })
export class UserGateway
implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect {
@WebSocketServer() server: Server;
private logger: Logger = new Logger('UserGateway');
constructor(private userService: UserService) {}

afterInit() {
this.logger.log('Init');
}

handleDisconnect(client: Socket) {
const user_id = client.request.url.split('user_id=')[1].split('&')[0];
this.userService.setOnlineStatus(false, user_id);
pubsub.publish('userOnline', {
userOnline: { id: user_id, online: false },
});
this.logger.log(`Client disconnected: ${user_id}`);
}

handleConnection(client: Socket) {
const user_id = client.request.url.split('user_id=')[1].split('&')[0];
this.userService.setOnlineStatus(true, user_id);
pubsub.publish('userOnline', { userOnline: { id: user_id, online: true } });
this.logger.log(`Client connected: ${user_id}`);
}
}
7 changes: 7 additions & 0 deletions backend/src/user/user.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ type User {
firstName: String!
lastName: String!
createdAt: String!
online: Boolean
avatar: File
}

Expand Down Expand Up @@ -49,4 +50,10 @@ input SignInInput {

type Subscription {
userRegistred: User
userOnline: UserOnline
}

type UserOnline {
id: String
online: Boolean
}
3 changes: 2 additions & 1 deletion backend/src/user/user.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import { UserService } from './user.service';
import { UserResolver } from './user.resolver';
import { FileService } from 'src/file/file.service';
import { FileEntity } from 'src/file/file.entity';
import { UserGateway } from './user.gateway';

@Module({
imports: [TypeOrmModule.forFeature([UserEntity, FileEntity])],
providers: [UserResolver, UserService, FileService],
providers: [UserResolver, UserService, FileService, UserGateway],
})
export class UserModule {}
17 changes: 7 additions & 10 deletions backend/src/user/user.resolver.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
import {
Mutation,
Args,
Context,
Query,
Resolver,
Subscription,
} from '@nestjs/graphql';
import { UnprocessableEntityException, UseGuards } from '@nestjs/common';
import { Mutation, Args, Query, Resolver, Subscription } from '@nestjs/graphql';
import { UseGuards } from '@nestjs/common';
import { UserService } from './user.service';
import { SignUpInput, SignInInput } from './dto/auth.inputs';
import { User } from '../graphql';
import { AuthGuard } from '../guards/auth.guard';
import { UserEntity } from './user.entity';
import { CurrentUser } from './user.decorator';
Expand Down Expand Up @@ -86,4 +78,9 @@ export class UserResolver {
userRegistred() {
return pubsub.asyncIterator('userRegistred');
}

@Subscription(() => String)
userOnline() {
return pubsub.asyncIterator('userOnline');
}
}
9 changes: 9 additions & 0 deletions backend/src/user/user.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export class UserService {
firstName,
lastName,
avatar: avatar ? { id: avatar.id } : null,
online: true,
},
'secret',
);
Expand Down Expand Up @@ -113,6 +114,14 @@ export class UserService {
return true;
}

async setOnlineStatus(online: boolean, id: string) {
await this.userRepo
.createQueryBuilder('user')
.update(UserEntity, { online })
.where('id = :id', { id })
.execute();
}

async signIn({ email, password }: SignInInput) {
const user = await this.userRepo.findOne({
relations: ['avatar'],
Expand Down
Loading

0 comments on commit 23e3ff2

Please sign in to comment.