import { HttpClient } from '@angular/common/http' ; import { Injectable } from '@angular/core' ; import { combineLatest , Observable , of , from } from 'rxjs' ; import { map , mergeMap , catchError } from 'rxjs/operators' ; import { friendInvitationConstants , Friends , Game , GameOperations , GameStatus , Invitation , QueryParam , QueryParams , User , RoutesConstants , Question , UserStatus } from './../../../lib/shared/model' ; import { CONFIG } from './../../environments/environment' ; import { DbService } from './../db-service' ; import { Country } from 'shared-library/shared/mobile/component/countryList/model/country.model' ; import { Utils } from './utils' ; @ Injectable ( ) export class UserService { private RC = RoutesConstants ; constructor ( private http , private dbService , private utils ) { } loadUserProfile ( user ) { return this . dbService . valueChanges ( 'users' , user . userId ) . pipe ( map ( u => { if ( u ) { const userInfo = user ; user = u ; user . idToken = userInfo . idToken ; user . authState = userInfo . authState ; } else { const dbUser = Object . assign ( { } , user ) ; delete dbUser . authState ; delete dbUser . profilePictureUrl ; console . log ( 'db User ====> ' , dbUser ) ; this . dbService . setDoc ( 'users' , dbUser . userId , dbUser ) ; } return user ; } ) , mergeMap ( u => this . getUserProfileImage ( u ) ) ) ; } getOtherUserGamePlayedStat ( userId , friendList ) { const gamesPlayedWithObs = friendList . map ( friendId => this . dbService . valueChanges ( 'users' , `/${ userId }/game_played_with/${ friendId }` ) ) ; return combineLatest ( gamesPlayedWithObs ) . pipe ( map ( ( values ) => { return values . map ( ( value , index ) => { if ( value ) { value . userId = friendList [ index ] ; return value ; } else { value = { } ; value . userId = friendList [ index ] ; value . created_uid = friendList [ index ] ; return value ; } } ) ; } ) , catchError ( error => { console . log ( error ) ; return of ( null ) ; } ) ) ; } loadAccounts ( user ) { return this . dbService . valueChanges ( 'accounts' , user . userId ) ; } saveUserProfile ( user ) { const url = `${ CONFIG . functionsUrl }/user/profile` ; user . roles = ( ! user . roles ) ? { } : user . roles ; const dbUser = Object . assign ( { } , user ) ; delete dbUser . authState ; delete dbUser . profilePictureUrl ; return this . http . post < User > ( url , { user : dbUser } ) ; } addFeedback ( feedback ) { return this . dbService . CreateDocWithoutDocID ( 'feedback' , feedback ) ; } getCountries ( ) { return this . dbService . valueChanges ( 'countries' ) ; } loadOtherUserProfile ( userId ) { const url = `${ CONFIG . functionsUrl }/user/${ userId }` ; return this . http . get < User > ( url ) ; } loadOtherUserProfileWithExtendedInfo ( userId ) { const url = `${ CONFIG . functionsUrl }/user/extendedInfo/${ userId }` ; return this . http . get < User > ( url ) ; } loadUserInvitationsInfo ( userId , invitedUserEmail , invitedUserId ) { const queryParams = { condition : [ { name : 'created_uid' , comparator : '==' , value : userId } , { name : 'email' , comparator : '==' , value : invitedUserEmail } ] , limit : 1 } ; return combineLatest ( this . dbService . valueChanges ( 'invitations' , '' , queryParams ) , this . dbService . valueChanges ( 'friends' , userId ) ) . pipe ( map ( values => { if ( values [ 1 ] && values [ 1 ] . myFriends && values [ 1 ] . myFriends . some ( ( friend => friend [ invitedUserId ] ) ) ) { return { 'email' : invitedUserEmail , 'created_uid' : null , 'status' : 'approved' } ; } else if ( values [ 0 ] . length > 0 ) { return values [ 0 ] [ 0 ] ; } else { return { 'email' : invitedUserEmail , 'created_uid' : null , 'status' : 'add' } ; } } ) ) ; } getUserProfileImage ( user ) { if ( user . profilePicture && user . profilePicture !== '' ) { user . profilePictureUrl = this . utils . getImageUrl ( user , 263 , 263 , '400X400' ) ; return of ( user ) ; } else { user . profilePictureUrl = '/assets/images/default-avatar-small.png' ; return of ( user ) ; } } setSubscriptionFlag ( userId ) { this . dbService . updateDoc ( 'users' , userId , { isSubscribed : true } ) ; } saveUserInvitations ( obj ) { const url = `${ CONFIG . functionsUrl }/friend/invitation` ; return this . http . post < any > ( url , obj ) ; } checkInvitationToken ( obj ) { const url = `${ CONFIG . functionsUrl }/friend` ; return this . http . post < any > ( url , obj ) ; } loadUserFriends ( userId ) { return this . dbService . valueChanges ( 'friends' , userId ) ; } loadFriendInvitations ( email ) { const queryParams = new QueryParams ( ) ; queryParams . condition = [ ] ; let queryParam = new QueryParam ( 'email' , '==' , email ) ; queryParams . condition . push ( queryParam ) ; queryParam = new QueryParam ( 'status' , '==' , friendInvitationConstants . PENDING ) ; queryParams . condition . push ( queryParam ) ; return this . dbService . valueChanges ( 'invitations' , '' , queryParams ) . pipe ( map ( invitations => invitations ) ) ; } setInvitation ( invitation ) { return from ( this . dbService . updateDoc ( 'invitations' , invitation . id , invitation ) ) ; } getGameInvites ( user ) { if ( user && user . userId ) { const queryParams1 = { condition : [ { name : 'GameStatus' , comparator : '==' , value : GameStatus . WAITING_FOR_FRIEND_INVITATION_ACCEPTANCE } , { name : 'playerId_1' , comparator : '==' , value : user . userId } , { name : 'gameOver' , comparator : '==' , value : false } ] , orderBy : [ { name : 'turnAt' , value : 'desc' } ] } ; const query1 = this . dbService . valueChanges ( 'games' , '' , queryParams1 ) ; const queryParams2 = { condition : [ { name : 'GameStatus' , comparator : '==' , value : GameStatus . WAITING_FOR_RANDOM_PLAYER_INVITATION_ACCEPTANCE } , { name : 'playerId_1' , comparator : '==' , value : user . userId } , { name : 'gameOver' , comparator : '==' , value : false } ] , orderBy : [ { name : 'turnAt' , value : 'desc' } ] } ; const query2 = this . dbService . valueChanges ( 'games' , '' , queryParams2 ) ; return combineLatest ( query1 , query2 ) . pipe ( map ( ( data ) => data [ 0 ] . concat ( data [ 1 ] ) ) , map ( gs => gs . map ( g => Game . getViewModel ( g ) ) . sort ( ( a , b ) => b . turnAt - a . turnAt ) ) ) ; } else { return of < Game [ ] > ( [ ] ) ; } } rejectGameInvitation ( gameId ) { return this . http . put ( `${ CONFIG . functionsUrl }/game/${ gameId }` , { operation : GameOperations . REJECT_GAME } ) ; } updateUser ( user ) { const dbUser = Object . assign ( { } , user ) ; return from ( this . dbService . setDoc ( 'users' , dbUser . userId , dbUser ) ) ; } addUserLives ( userId ) { const url = `${ CONFIG . functionsUrl }/user/update-lives` ; return this . http . post < any > ( url , { userId : userId } ) ; } checkDisplayName ( displayName ) { const url = `${ CONFIG . functionsUrl }/${ this . RC . USER }/${ this . RC . CHECK }/${ this . RC . DISPLAY_NAME }/${ encodeURIComponent ( displayName ) }` ; return this . http . get < any > ( url ) ; } getAddressByLatLang ( latlong ) { const url = `${ CONFIG . functionsUrl }/${ this . RC . USER }/${ this . RC . ADDRESS_BY_LAT_LANG }/${ latlong }` ; return this . http . get < any > ( url ) ; } getAddressSuggestions ( address ) { const url = `${ CONFIG . functionsUrl }/${ this . RC . USER }/${ this . RC . ADDRESS_SUGGESTION }/${ address }` ; return this . http . get < any > ( url ) ; } getUserStatus ( user ) { return this . dbService . valueChanges ( 'user_status' , user . userId ) . pipe ( map ( u => { user . online = ( u ) ? u . online : false ; return user ; } , ( error ) => { return user ; } ) ) ; } updateUserStatus ( userStatus ) { this . dbService . updateDoc ( 'user_status' , userStatus . userId , userStatus ) ; } firstQuestionSetBits ( userId ) { const url = `${ CONFIG . functionsUrl }/user/add-bits-first-question` ; return this . http . get < any > ( url ) ; } }