Просмотр исходного кода

Merge branch 'brian_dev_146' of fyindr/siimee into dev

tags/0.0.3^2
maeda 3 лет назад
Родитель
Сommit
ba375174f2

+ 2
- 1
.gitignore Просмотреть файл

@@ -6,4 +6,5 @@ dist-ssr
6 6
 **/.env
7 7
 .nyc_output
8 8
 **/generated/_*
9
-**/.vscode
9
+**/.vscode
10
+**/*.vim

+ 9
- 4
backend/db/data-generator/config.json Просмотреть файл

@@ -30,12 +30,17 @@
30 30
         "91401",
31 31
         "97075"
32 32
     ],
33
-    "resKeys": [1, 2, 3, 4, 5, 6],
33
+    "scoreKeys": [1, 2, 3, 4, 5, 6],
34
+    "nameKey": 7,
35
+    "emailKey": 8,
36
+    "passwordKey": 9,
34 37
     "zipcodeKey": 10,
35 38
     "mediaKey": 12,
36 39
     "langKey": 13,
40
+    "durationKey": 14,
41
+    "presenceKey": 15,
37 42
     "blurbKey": 16,
38
-    "comment": "Make this match profiler.js complete profile constructor",
39
-    "prefKeys": [10, 14, 15, 17, 18, 19],
40
-    "maxDistanceKey": 19
43
+    "urgencyKey": 17,
44
+    "pronounsKey": 18,
45
+    "distanceKey": 19
41 46
 }

+ 2
- 2
backend/db/data-generator/index.js Просмотреть файл

@@ -138,10 +138,10 @@ const generateResponses = profiles => {
138 138
                     case config.langKey:
139 139
                         resToEdit.val = random.language()
140 140
                         break
141
-                    case 10:
141
+                    case config.durationKey:
142 142
                         resToEdit.val = random.duration()
143 143
                         break
144
-                    case 11:
144
+                    case config.presenceKey:
145 145
                         resToEdit.val = random.location()
146 146
                         break
147 147
                     case config.blurbKey:

+ 49
- 25
backend/lib/routes/membership/active.js Просмотреть файл

@@ -62,48 +62,72 @@ module.exports = {
62 62
         auth: false,
63 63
         cors: true,
64 64
         handler: async function (request, h) {
65
-            const { membershipService, profileService } =
65
+            const { membershipService, profileService, userService } =
66 66
                 request.server.services()
67 67
             const membershipType = request.query.type
68 68
 
69 69
             const profileId = request.params.profile_id
70
-            let groupings = await membershipService.findGroupingsByProfileId(
70
+            const groupings = await membershipService.findGroupingsByProfileId(
71 71
                 profileId,
72 72
                 membershipType,
73 73
             )
74
-            let memberships = await membershipService.findMemberships(
75
-                groupings.map(grouping => grouping.grouping_id),
74
+            const groupingIds = groupings.map(grouping => grouping.grouping_id)
75
+            const memberships = await membershipService.findMemberships(
76
+                groupingIds,
77
+            )
78
+            const profileIds = memberships
79
+                .filter(membership => membership.profile_id != profileId)
80
+                .map(membership => membership.profile_id)
81
+
82
+            /** Assemble complete profiles to reference and pass */
83
+            const completedProfiles = await profileService.getProfilesFor(
84
+                profileIds,
85
+                'participant',
76 86
             )
77 87
 
78 88
             /**
79 89
              * Heavily process the result by storing just a profile_id
80 90
              * and attach complete profiles
91
+             * !: This still assumes only ONE other profile
92
+             * TODO: should be refactored to many other profiles
81 93
              */
82
-            let pIds = groupings.reduce((ids, grouping) => {
83
-                grouping.profiles.forEach(p => {
84
-                    if (p.profile_id == profileId) return
85
-                    ids.push(p.profile_id)
86
-                    grouping.profile = p.profile_id
87
-                })
94
+            const reformattedGroupings = groupings.map(grouping => {
95
+                const otherPid = grouping.profiles.find(
96
+                    p => p.profile_id != profileId,
97
+                ).profile_id
98
+                grouping.profile = completedProfiles.find(
99
+                    p => otherPid == p.profile_id,
100
+                )
101
+                grouping.is_paired = _activeGroupingIds(memberships).includes(
102
+                    grouping.grouping_id,
103
+                )
88 104
                 delete grouping.profiles
89
-                return ids
90
-            }, [])
105
+                return grouping
106
+            })
91 107
 
92
-            /** Assemble complete profiles to reference and pass */
93
-            const completedProfiles = await profileService.getProfilesFor(
94
-                pIds,
95
-                'participant',
96
-                false,
108
+            /** Grabs revealTags */
109
+            const revealTags = await profileService.getTagsFor(
110
+                profileIds,
111
+                groupingIds,
112
+                'reveal',
113
+            )
114
+
115
+            /** If the revealTags exist, the completedProfile's hidden info is
116
+             * removed and replaced with the completedProfile's user information
117
+             * Otherwise the completedProfiles remain unchanged
118
+             */
119
+            const user = await userService.findById(
120
+                completedProfiles.map(p => p.user_id),
97 121
             )
98
-            const reformattedGroupings = groupings.map(g => {
99
-                completedProfiles.forEach(p => {
100
-                    g.profile = g.profile == p.profile_id ? p : g.profile
122
+
123
+            // TODO: Refactor this. Is it safe to always use completedProfiles[0]?
124
+            if (revealTags && user) {
125
+                revealTags.forEach(t => {
126
+                    if (!t.tag.tag_description) return
127
+                    completedProfiles[0][t.tag.tag_description] =
128
+                        user[t.tag.tag_description]
101 129
                 })
102
-                g.is_paired = _activeGroupingIds(memberships).includes(
103
-                    g.grouping_id,
104
-                )
105
-                return g
106
-            })
130
+            }
107 131
 
108 132
             try {
109 133
                 return {

+ 30
- 25
backend/lib/routes/membership/reveal.js Просмотреть файл

@@ -31,12 +31,12 @@ module.exports = {
31 31
         auth: false,
32 32
         cors: true,
33 33
         handler: async function (request, h) {
34
-            const { membershipService, profileService } =
34
+            const { membershipService, profileService, userService } =
35 35
                 request.server.services()
36 36
             const grouping_id = request.params.grouping_id
37 37
             const { profile_id, tag_id } = request.query
38 38
             try {
39
-                const tags = await profileService.revealProfileInfo({
39
+                const associations = await profileService.revealProfileInfo({
40 40
                     profile_id,
41 41
                     grouping_id,
42 42
                     tag_id,
@@ -50,39 +50,44 @@ module.exports = {
50 50
                 const idsInGroup = memberships.map(
51 51
                     membership => membership.profile_id,
52 52
                 )
53
-
53
+                if (idsInGroup.length > 2)
54
+                    return console.error(
55
+                        'ERROR: idsInGroup cannot have more than 2 entries: ',
56
+                        idsInGroup,
57
+                    )
54 58
                 // Grab User Info from Users Table
55
-                const completeProfile = await profileService.getProfilesFor([profile_id], 'participant')
59
+                const completeProfile = await profileService.getProfilesFor(
60
+                    [profile_id],
61
+                    'participant',
62
+                )
63
+                const userInfo = await userService.findById(
64
+                    completeProfile[0].user_id,
65
+                )
56 66
 
57 67
                 // Grab the TagAssociation that matches the revealed profile
58
-                // TODO: Check if there are multiple matching tags(?)(there shouldn't be)
59
-                const returnedTag = () => {
60
-                    let matchingTag
61
-                    tags.forEach(tagAssoc => {
62
-                        if (tagAssoc.grouping_id === grouping_id &&
63
-                            tagAssoc.profile_id === profile_id &&
64
-                            tagAssoc.tag_id === tag_id) {
65
-                            matchingTag = tagAssoc
66
-                        }
67
-                    })
68
-                    if (matchingTag)
69
-                        return matchingTag
70
-                    return console.error('ERROR: No matching tagAssociation')
71
-                }
72
-
73
-                const tag_description = returnedTag().tag.tag_description
74
-                // TODO: Refactor completeProfile[0]... code smell
75
-                const revealInfo = completeProfile[0][tag_description]
68
+                // TODO: Check if there are multiple matching associations(?)(there shouldn't be)
69
+                let matchingAssociation = null
70
+                associations.forEach(tagAssoc => {
71
+                    if (
72
+                        tagAssoc.grouping_id === grouping_id &&
73
+                        tagAssoc.profile_id === profile_id &&
74
+                        tagAssoc.tag_id === tag_id
75
+                    ) {
76
+                        matchingAssociation = tagAssoc
77
+                    }
78
+                })
79
+                const description = matchingAssociation.tag.tag_description
76 80
 
77 81
                 idsInGroup.forEach(profile_id => {
78 82
                     request.server.methods.notify(
79 83
                         `${profile_id}.stonk`,
80 84
                         {
81 85
                             name: 'REVEALED_INFO',
82
-                            revealed_info: revealInfo,
86
+                            revealed_info: userInfo[description],
87
+                            profile_id: completeProfile[0].profile_id,
83 88
                             grouping_id: grouping_id,
84 89
                             tag: tag_id,
85
-                            description: tag_description,
90
+                            description,
86 91
                             type: 'info',
87 92
                         },
88 93
                         h,
@@ -92,7 +97,7 @@ module.exports = {
92 97
                     .response({
93 98
                         ok: true,
94 99
                         handler: pluginConfig.handlerType,
95
-                        data: { tags },
100
+                        data: { tags: associations },
96 101
                     })
97 102
                     .code(200)
98 103
             } catch (err) {

+ 21
- 16
backend/lib/routes/profile/queue.js Просмотреть файл

@@ -23,7 +23,11 @@ const responseSchemas = {
23 23
 
24 24
 const validators = {
25 25
     params: params.profileId,
26
-    query: Joi.object({include_profile: Joi.bool(), limit: Joi.number(), offset: Joi.number()}),
26
+    query: Joi.object({
27
+        include_profile: Joi.bool(),
28
+        limit: Joi.number(),
29
+        offset: Joi.number(),
30
+    }),
27 31
 }
28 32
 
29 33
 module.exports = {
@@ -37,17 +41,16 @@ module.exports = {
37 41
         cors: true,
38 42
         handler: async function (request, h) {
39 43
             const { profile_id } = request.params
40
-            const { include_profile, limit, offset} = request.query
44
+            const { limit, offset } = request.query
41 45
             const { profileService, matchQueueService } =
42 46
                 request.server.services()
43 47
 
44
-            const queue = await matchQueueService.getQueue(profile_id, limit, offset)
48
+            const queue = await matchQueueService.getQueue(
49
+                profile_id,
50
+                limit,
51
+                offset,
52
+            )
45 53
             const queueIds = queue.map(entry => entry.target_id)
46
-            const res = {
47
-                ok: true,
48
-                handler: pluginConfig.handlerType,
49
-                data: queueIds,
50
-            }
51 54
 
52 55
             // HELP: I think there's an issue here
53 56
             // queueIds spits out the queue profiles in the correct order
@@ -57,15 +60,17 @@ module.exports = {
57 60
             //     'include_profile results',
58 61
             //     await profileService.getProfilesFor(queueIds),
59 62
             // )
60
-            if (include_profile) {
61
-                res.data = await profileService.getProfilesFor(
62
-                    queueIds,
63
-                    'participant',
64
-                    false,
65
-                )
66
-            }
67 63
             try {
68
-                return h.response(res).code(200)
64
+                return h
65
+                    .response({
66
+                        ok: true,
67
+                        handler: pluginConfig.handlerType,
68
+                        data: await profileService.getProfilesFor(
69
+                            queueIds,
70
+                            'participant',
71
+                        ),
72
+                    })
73
+                    .code(200)
69 74
             } catch (err) {
70 75
                 return h
71 76
                     .response({

+ 2
- 0
backend/lib/schemas/profiles.js Просмотреть файл

@@ -13,6 +13,8 @@ const singleProfile = Joi.object({
13 13
     responses: surveyResponseSchema.list,
14 14
     reveal: Joi.array().items(),
15 15
     tags: tagSchema.list,
16
+    image: Joi.any(),
17
+    blurb: Joi.any(),
16 18
     user_type: Joi.any(),
17 19
     user: userSchema.single,
18 20
     profile_description: Joi.string().allow(null, ''),

+ 4
- 42
backend/lib/services/profile/index.js Просмотреть файл

@@ -62,8 +62,7 @@ module.exports = class ProfileService extends Schmervice.Service {
62 62
         matchingProfile.tags = matchingProfile.tags.map(
63 63
             tag => this.tagLookup[tag.tag_id],
64 64
         )
65
-        const complete = new profiler.CompleteProfile(matchingProfile, true)
66
-        return this.setDefaults(complete)
65
+        return new profiler.CompleteProfile(matchingProfile)
67 66
     }
68 67
 
69 68
     async getCompleteProfilesFor(userId, type) {
@@ -76,8 +75,6 @@ module.exports = class ProfileService extends Schmervice.Service {
76 75
             .whereIn('profile_id', dedupedProfileIds)
77 76
             .withGraphFetched('tags')
78 77
             .withGraphFetched('responses')
79
-            // CHECKTHIS: Added this because we added user.user_name to CompleteProfile
80
-            // so without this, we get undefined user_name
81 78
             .withGraphFetched('user')
82 79
 
83 80
         return profiler.makeCompleteFromProfileEntries(
@@ -87,12 +84,12 @@ module.exports = class ProfileService extends Schmervice.Service {
87 84
         )
88 85
     }
89 86
 
90
-    async getProfilesFor(profileIdArray, type, includeResponses = true) {
87
+    async getProfilesFor(profileIdArray, type) {
91 88
         const { Profile } = this.server.models()
92 89
         await this._setScoreLookup()
93 90
         await this._setTagLookup()
94 91
 
95
-        // profilesEntries is profiles in dataaspect_labelsbase row order
92
+        // profilesEntries is profiles in database row order
96 93
         const profilesEntries = await Profile.query()
97 94
             .whereIn('profile_id', profileIdArray)
98 95
             .withGraphFetched('tags')
@@ -106,7 +103,6 @@ module.exports = class ProfileService extends Schmervice.Service {
106 103
             profileIdArray,
107 104
             profilesEntries,
108 105
             type,
109
-            includeResponses,
110 106
             this.tagLookup,
111 107
         )
112 108
     }
@@ -225,40 +221,6 @@ module.exports = class ProfileService extends Schmervice.Service {
225 221
         return allResponses
226 222
     }
227 223
 
228
-    /**
229
-     * Sets default profile attributes
230
-     * @param {object} complete
231
-     * @returns {object} updated profile
232
-     */
233
-    setDefaults(complete) {
234
-        let defaultValues = {
235
-            user_email: 'hidden@email.com',
236
-            user_name: 'Hidden Name',
237
-        }
238
-
239
-        let defaultProfile = {
240
-            ...complete,
241
-            user_email: defaultValues.user_email,
242
-            user_name: defaultValues.user_name,
243
-        }
244
-        console.log('---')
245
-        console.log('defaultProfile: ', defaultProfile.user_email)
246
-        if (!complete.reveal.length) return defaultProfile // nothing to reveal
247
-
248
-        // swap out values of keys that are not found as complete.reveal.tag.tag_description values
249
-        for (let [attribute, defaultVal] of Object.entries(defaultValues)) {
250
-            if (
251
-                typeof complete.reveal.find(
252
-                    tag => tag.tag_description == attribute,
253
-                ) == 'undefined'
254
-            )
255
-                complete[attribute] = defaultVal
256
-        }
257
-        console.log('complete: ', complete.user_email)
258
-
259
-        return complete
260
-    }
261
-
262 224
     /**
263 225
      * Delete a profile
264 226
      * @param {number} userId
@@ -422,7 +384,7 @@ module.exports = class ProfileService extends Schmervice.Service {
422 384
             await TagAssociation.query().insert(association)
423 385
             return await this.getTagsFor(association.profile_id)
424 386
         } else {
425
-            return console.error('tag association already exists')
387
+            return console.error('ERROR =>: tag association already exists')
426 388
         }
427 389
     }
428 390
 }

+ 79
- 62
backend/lib/services/profile/profiler.js Просмотреть файл

@@ -1,93 +1,110 @@
1 1
 const config = require('../../../db/data-generator/config.json')
2 2
 
3
+/**
4
+ * Unscored preferences used for filtering
5
+ * Does NOT include blurb, media languages
6
+ */
7
+const unscoredProfilePreferences = [
8
+    'zipcode',
9
+    'duration',
10
+    'presence',
11
+    'urgency',
12
+    'pronouns',
13
+    'distance',
14
+]
15
+const otherProfileInfo = ['blurb', 'media', 'lang']
16
+
3 17
 /**
4 18
  * Class to hold our retrieved profile information
5 19
  * in a convenient wrapper
6 20
  * !: This needs to match the responseSchema in profiles.js
7 21
  */
8 22
 class CompleteProfile {
9
-    constructor(profile, includeResponses = false, type) {
23
+    constructor(profile, type) {
10 24
         this.user_id = profile.user_id // int user_id
11 25
         this.profile_id = profile.profile_id // int profile_id
12
-        this.user_name = profile.user.user_name // string user_name
13
-        this.user_email = profile.user.user_email
14
-        this.responses = []
26
+        this.responses = profile.responses
15 27
         this.user_type = type
16
-        this.tags = profile.tags.filter(t => t.tag_category != 'reveal')
17 28
 
18
-        // TODO: generalize this for multiple images, and languages
19
-        this.profile_description = ''
20
-        this.profile_media = []
21
-        this.profile_languages = []
22
-        this.profile_prefs = {}
23
-
24
-        // TODO: Use reveal tags to add or remove information from profile!
25
-        // TODO: ---
26
-        // TODO: Use reveal tags to rebuild profile based on group/membership
27
-        // TODO: and include for certain profiles
29
+        this.profile_prefs = this.getPrefsFromResponses(this.responses)
28 30
 
31
+        otherProfileInfo.forEach(prefName => {
32
+            if (prefName == 'blurb') {
33
+                this.profile_description = this.responses.find(
34
+                    r => r.response_key_id === config.blurbKey,
35
+                ).val
36
+            } else if (['media', 'lang'].includes(prefName)) {
37
+                const key =
38
+                    prefName == 'media'
39
+                        ? `profile_${prefName}`
40
+                        : [`profile_${prefName}uages`]
41
+                this[key] = this.responses
42
+                    .filter(r => r.response_key_id === config[`${prefName}Key`])
43
+                    .map(r => r.val)
44
+            }
45
+        })
46
+        // TODO: These should be getters
47
+        this.user_name = 'bleh'
48
+        this.user_email = 'bleh@bleh.com'
29 49
         this.reveal = profile.tags.filter(t => t.tag_category == 'reveal')
30
-        // TODO: filter these correctly
31
-        if (profile?.responses?.length && includeResponses) {
32
-            // [] of all "profile" responses
33
-            this.responses = profile.responses
34
-            // image, language, duration, presence, blurb, urgency, role, pronouns, distance
35
-            const prefs = [
36
-                'zipcode',
37
-                'duration',
38
-                'presence',
39
-                'urgency',
40
-                'pronouns',
41
-                'distance',
42
-            ]
43
-            const prefsKeys = config.prefKeys
44
-            prefs.forEach((pref, i) => {
45
-                this.profile_prefs[pref] = this.responses.find(
46
-                    r => r.response_key_id === prefsKeys[i],
47
-                )
48
-            })
49
-            this.profile_description = this.responses.find(
50
-                r => r.response_key_id === config.blurbKey,
50
+        this.tags = profile.tags.filter(t => t.tag_category !== 'reveal')
51
+    }
52
+    /** Map pref name to dB key associated with preference */
53
+    get byPrefName() {
54
+        return unscoredProfilePreferences.reduce((byPref, prefName) => {
55
+            byPref[prefName] = this.responses.find(
56
+                r => config[`${prefName}Key`] == r.response_key_id,
51 57
             ).val
52
-            this.profile_media = this.responses
53
-                .filter(r => r.response_key_id === config.mediaKey)
54
-                .map(r => r.val)
55
-            this.profile_languages = this.responses
56
-                .filter(r => r.response_key_id === config.langKey)
57
-                .map(r => r.val)
58
-        }
58
+            return byPref
59
+        }, {})
60
+    }
61
+    getPrefsFromResponses(responses) {
62
+        if (!responses.length) return
63
+        const prefs = {}
64
+        unscoredProfilePreferences.forEach(prefName => {
65
+            prefs[prefName] = this.byPrefName[prefName]
66
+        })
67
+        return prefs
59 68
     }
60 69
 }
61
-const _makeCompleteProfile = (
62
-    profileEntry,
63
-    type,
64
-    tagLookup,
65
-    includeResponses,
66
-) => {
70
+const _makeCompleteProfile = (profileEntry, type, tagLookup) => {
67 71
     profileEntry.tags = profileEntry.tags.map(tag => tagLookup[tag.tag_id])
68
-    return new CompleteProfile(profileEntry, includeResponses, type)
72
+    const complete = new CompleteProfile(profileEntry, type)
73
+    return complete
69 74
 }
70 75
 
76
+/**
77
+ * Get complete profiles and return in order
78
+ * @param {Array} orderedProfileIds
79
+ * @param {Array} profilesEntries
80
+ * @param {String} type
81
+ * @param {Object} tagLookup
82
+ * @returns {Array}
83
+ */
71 84
 const makeOrderedCompleteProfiles = (
72 85
     orderedProfileIds,
73 86
     profilesEntries,
74 87
     type,
75
-    includeResponses,
76 88
     tagLookup,
77 89
 ) => {
78
-    const completeProfiles = []
79
-    orderedProfileIds.forEach(pid => {
80
-        profilesEntries.forEach(entry => {
81
-            if (entry.profile_id != pid) return
82
-            completeProfiles.push(
83
-                _makeCompleteProfile(entry, type, tagLookup, includeResponses),
84
-            )
85
-        })
90
+    return orderedProfileIds.map(pid => {
91
+        const found = profilesEntries.find(entry => entry.profile_id == pid)
92
+        return _makeCompleteProfile(found, type, tagLookup)
86 93
     })
87
-    return completeProfiles
88 94
 }
89
-const makeCompleteFromProfileEntries = (profilesEntries, type, tagLookup) =>
90
-    profilesEntries.map(entry => _makeCompleteProfile(entry, type, tagLookup))
95
+
96
+/**
97
+ * Get complete profiles from dB rows
98
+ * @param {Array} profilesEntries
99
+ * @param {String} type
100
+ * @param {Object} tagLookup
101
+ * @returns {Array}
102
+ */
103
+const makeCompleteFromProfileEntries = (profilesEntries, type, tagLookup) => {
104
+    return profilesEntries.map(entry =>
105
+        _makeCompleteProfile(entry, type, tagLookup),
106
+    )
107
+}
91 108
 
92 109
 module.exports = {
93 110
     CompleteProfile,

+ 2
- 7
backend/lib/services/profile/scorer.js Просмотреть файл

@@ -18,13 +18,8 @@ const makeScoreLookup = (aspects, labels) => {
18 18
     return scoreLookup
19 19
 }
20 20
 
21
-const _isScorableResponse = res_key_id => {
22
-    let isScorable = false
23
-    if (config.resKeys.includes(res_key_id)) {
24
-        isScorable = true
25
-    }
26
-    return isScorable
27
-}
21
+const _isScorableResponse = res_key_id =>
22
+    config.scoreKeys.includes(res_key_id) ? true : false
28 23
 
29 24
 const scoreResponses = (seeker, potentialMatch, prescoreLookup) => {
30 25
     if (seeker.responses.length != potentialMatch.responses.length)

+ 0
- 1
frontend/src/components/NamePlate.vue Просмотреть файл

@@ -3,7 +3,6 @@
3 3
     section(:class='{ box: !isList }' v-if='pid')
4 4
         router-link(:to='`/profile/${pid}`' disabled)
5 5
             h1.text-capitalize {{ name }}
6
-                span O
7 6
             p.text-capitalize {{ role }} 
8 7
                 span.text-capitalize(v-if='isList')
9 8
                     span.text-capitalize | {{ locale }}

+ 3
- 2
frontend/src/components/ProfileCard.vue Просмотреть файл

@@ -66,8 +66,9 @@ import TagList from './TagList.vue'
66 66
 import PairingButton from './PairingButton.vue'
67 67
 
68 68
 const router = useRouter()
69
-const isPaired = ref(true)
70
-// const isPaired = ref(false)
69
+// NOTE: toggle to use for testing pairing
70
+// const isPaired = ref(true)
71
+const isPaired = ref(false)
71 72
 
72 73
 const props = defineProps({
73 74
     card: {

+ 2
- 0
frontend/src/entities/profile/profile.schema.js Просмотреть файл

@@ -27,6 +27,8 @@ const profileSchema = {
27 27
         user_name: Joi.string(),
28 28
         user_id: Joi.number(),
29 29
         user_email: Joi.string(),
30
+        image: Joi.any(),
31
+        blurb: Joi.any(),
30 32
         profile_id: Joi.number(),
31 33
         profile_description: Joi.string().allow(null, ''),
32 34
         profile_media: Joi.array().items(Joi.string()),

+ 3
- 1
frontend/src/entities/response/response.schema.js Просмотреть файл

@@ -8,7 +8,9 @@ const responseSchema = Joi.object({
8 8
     profile_id: Joi.number(),
9 9
     response_id: Joi.number(),
10 10
     response_key_id: Joi.number(),
11
-    val: Joi.string(),
11
+    // TODO: troubleshoot later, suppressed validation warning for now
12
+    // val: Joi.string(),
13
+    val: Joi.any(),
12 14
 })
13 15
 
14 16
 export { responseSchema }

+ 2
- 1
frontend/src/services/grouping.service.js Просмотреть файл

@@ -1,6 +1,6 @@
1 1
 import { db } from '../utils/db.js'
2 2
 import { Grouping, Profile } from '../entities/index.js'
3
-
3
+import { ref } from 'vue'
4 4
 /**
5 5
  * Get Memberships associated with a single Profile from the database and
6 6
  * create a class from the data and
@@ -26,6 +26,7 @@ const fetchMembershipsByProfileId = async profileId => {
26 26
                     `/profile/${profileId}/tags/${grouping.grouping_id}`,
27 27
                 )
28 28
                 grouping.tags = [...targetTags, ...profileTags]
29
+                grouping.revealedFromNotification = ref([])
29 30
                 grouping._loading.value = false
30 31
                 validGroupingInstances.push(grouping)
31 32
             }

+ 9
- 5
frontend/src/services/notification.service.js Просмотреть файл

@@ -44,19 +44,23 @@ class StonkAlert extends Toaster {
44 44
         }
45 45
     }
46 46
     _appendTagsToGrouping(parsed) {
47
-        const foundGrouping = currentProfile.groupings.find(grouping =>
48
-            grouping.grouping_id === parsed.grouping_id
47
+        const foundGrouping = currentProfile.groupings.find(
48
+            grouping => grouping.grouping_id === parsed.grouping_id,
49 49
         )
50 50
         if (foundGrouping) {
51 51
             const tagFromNotification = {
52 52
                 is_active: 1,
53
-                tag_category: "reveal",
53
+                tag_category: 'reveal',
54
+                profile_id: parsed.profile_id,
54 55
                 tag_description: parsed.description,
55
-                tag_id: parsed.tag
56
+                tag_id: parsed.tag,
56 57
             }
57 58
             const target_desc = parsed.description
58 59
             tagFromNotification[target_desc] = parsed.revealed_info
59
-            foundGrouping.profile.tags.push(tagFromNotification)
60
+            foundGrouping.profile.reveal.push(tagFromNotification)
61
+            foundGrouping.revealedFromNotification.value.push(
62
+                tagFromNotification,
63
+            )
60 64
         }
61 65
     }
62 66
 }

+ 27
- 15
frontend/src/views/ChatView.vue Просмотреть файл

@@ -2,8 +2,13 @@
2 2
 main.view--chat
3 3
     header.mb6(v-if='profile && grouping')
4 4
         h3 chatting with:
5
-        p {{ target.profile_id }} | {{ grouping.profile.user_name }} | {{ grouping.profile.user_email }}
6
-
5
+        span {{ target.profile_id }} | 
6
+        span(v-if="grouping.revealedFromNotification.length")
7
+            span(v-for="revealed in grouping.revealedFromNotification")
8
+                span(v-if="revealed.profile_id === target.profile_id")
9
+                    span {{ revealed[revealed.tag_description] }} | 
10
+        span(v-else)
11
+            span  {{ grouping.profile.user_name }} | {{ grouping.profile.user_email }}
7 12
         h3 logged in as:
8 13
         p {{ profile.id }} | {{ profile._profile.user_name }} | {{ profile._profile.user_email }}
9 14
         //- p subscriptions: {{ profile.chatter.subscriptions }}
@@ -15,14 +20,18 @@ main.view--chat
15 20
                 button(@click='reveal(8)') reveal my email
16 21
                 // TODO: Remove later, only for testing
17 22
                 button(@click='checkData()') check data
18
-            p you revealed:
19
-                span(v-if="grouping.revealed[profile.id.value]")
20
-                    ul(v-for="reveal in grouping.revealed[profile.id.value]")
21
-                        li {{ reveal.description }} : {{ profile._profile[reveal.description] }}
22
-            p they revealed:
23
-                span(v-if="theyRevealed")
24
-                    ul(v-for="reveal in theyRevealed")
25
-                        li {{ reveal.description }} : {{ grouping.profile[reveal.description] }}
23
+            span(v-if="grouping.revealed[profile.id.value]")
24
+                p you revealed:
25
+                ul(v-for="reveal in [...new Set(grouping.revealed[profile.id.value])]")
26
+                    li {{ reveal.description }}
27
+            span(v-if="grouping.revealed[target.profile_id]")
28
+                p they revealed:
29
+                ul(v-for="reveal in grouping.revealed[target.profile_id]")
30
+                    li {{ reveal.description }}: {{ target[reveal.description] }}
31
+            span(v-if="grouping.revealedFromNotification.length")
32
+                p recently revealed:
33
+                ul(v-for="revealed in grouping.revealedFromNotification")
34
+                    li(v-if="revealed[revealed.tag_description] !== profile._profile[revealed.tag_description]") {{ revealed.tag_description }}: {{ revealed[revealed.tag_description] }}
26 35
 
27 36
     article
28 37
         template(v-if='isLoading')
@@ -66,14 +75,13 @@ export default {
66 75
         toSend: '',
67 76
         messages: [],
68 77
         grouping: {},
78
+        them: {},
69 79
     }),
70 80
     // TODO: Make sure grouping.profile.profile_id actually exists
71 81
     computed: {
72 82
         theyRevealed() {
73
-            return this.grouping && this.grouping.revealed[this.grouping.profile.profile_id] ?
74
-                this.grouping.revealed[this.grouping.profile.profile_id] :
75
-                []
76
-        }
83
+            return this.them
84
+        },
77 85
     },
78 86
     watch: {
79 87
         async profile() {
@@ -88,6 +96,7 @@ export default {
88 96
         this.loadTargetProfile()
89 97
         currentProfile._loading.value = true
90 98
         this.grouping = this.getGrouping()
99
+        this.them = this.grouping.profile
91 100
         this.messages = await currentProfile.chatter.getHistory(this.grouping.grouping_name)
92 101
         console.log('this.messages :>> ', this.messages)
93 102
         currentProfile.chatter.setOnMessage(this._onMessage)
@@ -100,7 +109,7 @@ export default {
100 109
          },
101 110
         // TODO: remove, only for testing reveal()
102 111
         async checkData() {
103
-            console.log(currentProfile)
112
+            console.log('currentProfile :=>', currentProfile)
104 113
         },
105 114
         /**
106 115
          * Pubnub message callback fires when message event
@@ -113,6 +122,9 @@ export default {
113 122
         },
114 123
         // TODO: test this
115 124
         getGrouping() {
125
+            if (this.$route.params.pid === currentProfile.profile_id) {
126
+                console.warn('WARNING :=> You cannot chat with yourself!!!')
127
+            }
116 128
             return currentProfile.groupings.find(
117 129
                 g => g.profile.profile_id == this.$route.params.pid,
118 130
             )

+ 3
- 3
frontend/src/views/SurveyView.vue Просмотреть файл

@@ -30,7 +30,7 @@ main.view--survey.f-col.start.w-full
30 30
                                 @input='storeResponseLike(step, q.response_key_id, q.response_key_prompt, profile[q.response_key_prompt])'
31 31
                                 @keyup.enter='step++'
32 32
                                 v-model='profile[q.response_key_prompt]'
33
-                            ) 
33
+                            )
34 34
                             label >{{ profile[q.response_key_prompt] }}
35 35
 
36 36
                         //- Aspects
@@ -85,7 +85,7 @@ import {
85 85
     signupUser,
86 86
 } from '@/services'
87 87
 
88
-import { maxDistanceKey } from '../../../backend/db/data-generator/config.json'
88
+import { distanceKey } from '../../../backend/db/data-generator/config.json'
89 89
 
90 90
 export default {
91 91
     props: {
@@ -248,7 +248,7 @@ export default {
248 248
                 Object.values(this.responseLikes),
249 249
             )
250 250
             const maxDistanceRes = survey.find(
251
-                res => res.response_key_id == maxDistanceKey,
251
+                res => res.response_key_id == distanceKey,
252 252
             )
253 253
             /**
254 254
              * Creating a profile only returns the created

Загрузка…
Отмена
Сохранить