Skip to content

Commit 7c9c45a

Browse files
negueSabreCatphillipthelen
authored
combined messages restyling - next round (#15386)
* split component prepare new views / states * extract empty and disabled state as components * fix empty state mail icon * first logic switching between modes, move page to /private-messages/index.vue * extract autoCompleteHelper.js * style header + start new message input * style plus button + focus input * state logic, types for sanity * WIP PM new Message started * add /members/username test * first design changes to messageCard * delete private message or chat - based on the mode * copy as todo * mention links to modal * report chat or private message * WIP likeButton * likeButton styling * hide like on private message cards * fix unit test * replace copy as todo - to just a copy to clipboard * style changes * menu position + like button width * dropdown items background + like font * fix like button padding * move api endpoints and tests around to group inbox methods + like for inbox private messages * restyle system messages * Dropdown Radius and Padding * WIP system messages * fix lint * copy delta commit of allowing liking own private messages * enable liking private messages * fix menu non hovered item icon color * fix import path * ignore background on system messages * requested changes + migration * update migration to update the unique id to some messages and delete the duplicates * migration based on users pagination * fix(migration): use Promise.all * change to bulkWrites per User, and all messages in one run (of a user) * check for array * use rest operator ... * skip sorting to get the users * remove migration, disable like for private messages without uniqueMessageId * lean+bulkWrite for likes, add time checks for like and auth for further debugging * add a limit 2 get the messages by uniqueId * Adding a simple server start script * remove pinned nodemon dep * fix inbox controller/tests * fix / requested style changes * fix empty state padding / * hide avatar weapons on messages - fix avatar spacing on messages * Hourglass Simplification (#15323) * begin removing obsolete tests * begin refactoring * update cron tests * cleanup * finish basic implementation of new logic * add more subscription tests * subscription test improvements * return nextHourglassDate again * fix gem limit * fix(test): short circuit this. * fix(admin): correct logic and style for shrimple subs * WIP(frontend): draft of main subs page view * fix hourglass count * Fix hourglass logic for upgrades * fix admin panel display * WIP(subs): extant Stripe state * fix admin panel strings * fix missing transaction type * add new field for cumulative subscription count * show date for hourglass bonus if it was received * fix test * feat(subscription): max Gems progress readout * fix(css): correct and refactor heights and selection states * fix(subs): correct border-radius and redirect * fix(stripe): correct redirect after success * Admin panel display fixes * don’t give additional HG for new sub if they already got one this month * fix issue with promo hourglasses * fix(subscription): update layout when gifting * fix(subscriptions): more gift layout revisions * fix(subscriptions): minor visual updates * fix(subs): pass autoRenews through Stripe * fix(subs): gifts DON't renew * fix(lint): unnecessary ternary * fix(lint): do negate object ig * fix(subs): try again on gifts * fix(subs): unhovery and un-12-monthy * fix bug with incorrectly giving HG bonus * remove only * fix test * fix test * fix(subs): also redirect to subs after gift sub * fix(subs): fix typeError * fix(g1g1): don't try to find Gems promo during bogo --------- Co-authored-by: Phillip Thelen <[email protected]> Co-authored-by: Kalista Payne <[email protected]> * chore(sprites): update subproject * fix(layout): tighten cancellation note * fix(subs): Google wording and HG escape * chore(testing): fake g1g1 dates * fix(subs): don't hide HG preview entirely * fix(subs): center next hourglass message * working validatedTextInput.vue within start-new-conversation-input-header.vue 🎉 * fix(git): remove changes from old develop * Revert "fix(git): remove changes from old develop" This reverts commit 0e30f7d. * fix(git): no actually just this file i guesss * adding an empty loading state, hiding * fought the avatar arch nemesis again * fix chatMessages (party chat) message spacing * move disabled text back to above the input area - re-enable input area * show disabled private messages top panel * fix font color * fixing uiStates - removing disabled - moving the own user check to the last * fix(lint): add missing prop defaults * fix(lint): object default should be fn * fix(chat): correct grammar in error * remove weapon position relative * revert most of avatar.vue changes, add back weapons in chat message UI * show date tooltip above system / skill messages * fix toggle disable icon position * trivial CSS cleanup * fix(typo): English syntax in test * chore(test): small style cleanup * chore(logging): revert debug function * chore(debug): remove timers from inbox like --------- Co-authored-by: SabreCat <[email protected]> Co-authored-by: Kalista Payne <[email protected]> Co-authored-by: Phillip Thelen <[email protected]>
1 parent 95142e3 commit 7c9c45a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+2320
-1327
lines changed

Diff for: .gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,5 @@ webpack.webstorm.config
4747

4848
# mongodb replica set for local dev
4949
mongodb-*.tgz
50-
/mongodb-data
50+
/mongodb-data*
5151
/.nyc_output

Diff for: package.json

+1
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@
110110
"start:simple": "node ./website/server/index.js",
111111
"debug": "gulp nodemon --inspect",
112112
"mongo:dev": "run-rs -v 5.0.23 -l ubuntu1804 --keep --dbpath mongodb-data --number 1 --quiet",
113+
"mongo:test": "run-rs -v 5.0.23 -l ubuntu1804 --keep --dbpath mongodb-data-testing --number 1 --quiet",
113114
"postinstall": "git config --global url.\"https://\".insteadOf git:// && gulp build && cd website/client && npm install",
114115
"apidoc": "gulp apidoc",
115116
"heroku-postbuild": ".heroku/report_deploy.sh"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import {
2+
generateUser,
3+
translate as t,
4+
} from '../../../../helpers/api-integration/v3';
5+
import common from '../../../../../website/common';
6+
7+
describe('GET /members/username/:username', () => {
8+
let user;
9+
10+
before(async () => {
11+
user = await generateUser();
12+
});
13+
14+
it('validates req.params.username', async () => {
15+
await expect(user.get('/members/username/')).to.eventually.be.rejected.and.eql({
16+
code: 400,
17+
error: 'BadRequest',
18+
message: t('invalidReqParams'),
19+
});
20+
});
21+
22+
it('returns a member\'s public data only', async () => {
23+
// make sure user has all the fields that can be returned by the getMember call
24+
const member = await generateUser({
25+
contributor: { level: 1 },
26+
backer: { tier: 3 },
27+
preferences: {
28+
costume: false,
29+
background: 'volcano',
30+
},
31+
secret: {
32+
text: 'Clark Kent',
33+
},
34+
});
35+
const memberRes = await user.get(`/members/username/${member.auth.local.username}`);
36+
expect(memberRes).to.have.all.keys([ // works as: object has all and only these keys
37+
'_id', 'id', 'preferences', 'profile', 'stats', 'achievements', 'party',
38+
'backer', 'contributor', 'auth', 'items', 'inbox', 'loginIncentives', 'flags',
39+
]);
40+
expect(Object.keys(memberRes.auth)).to.eql(['local', 'timestamps']);
41+
expect(Object.keys(memberRes.preferences).sort()).to.eql([
42+
'size', 'hair', 'skin', 'shirt',
43+
'chair', 'costume', 'sleep', 'background', 'tasks', 'disableClasses',
44+
].sort());
45+
46+
expect(memberRes.stats.maxMP).to.exist;
47+
expect(memberRes.stats.maxHealth).to.equal(common.maxHealth);
48+
expect(memberRes.stats.toNextLevel).to.equal(common.tnl(memberRes.stats.lvl));
49+
expect(memberRes.inbox.optOut).to.exist;
50+
expect(memberRes.inbox.canReceive).to.exist;
51+
expect(memberRes.inbox.messages).to.not.exist;
52+
expect(memberRes.secret).to.not.exist;
53+
54+
expect(memberRes.blocks).to.not.exist;
55+
});
56+
});

Diff for: test/api/v4/inbox/POST-inbox_message_like.test.js

+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import find from 'lodash/find';
2+
import {
3+
generateUser,
4+
translate as t,
5+
} from '../../../helpers/api-integration/v4';
6+
7+
/**
8+
* Checks the messages array if the uniqueMessageId has the like flag
9+
* @param {InboxMessage[]} messages
10+
* @param {String} uniqueMessageId
11+
* @param {String} userId
12+
* @param {Boolean} likeStatus
13+
*/
14+
function expectMessagesLikeStatus (messages, uniqueMessageId, userId, likeStatus) {
15+
const messageToCheck = find(messages, { uniqueMessageId });
16+
17+
expect(messageToCheck.likes[userId]).to.equal(likeStatus);
18+
}
19+
20+
// eslint-disable-next-line mocha/no-exclusive-tests
21+
describe('POST /inbox/like-private-message/:messageId', () => {
22+
let userToSendMessage;
23+
const getLikeUrl = messageId => `/inbox/like-private-message/${messageId}`;
24+
25+
before(async () => {
26+
userToSendMessage = await generateUser();
27+
});
28+
29+
it('returns an error when private message is not found', async () => {
30+
await expect(userToSendMessage.post(getLikeUrl('some-unknown-id')))
31+
.to.eventually.be.rejected.and.eql({
32+
code: 404,
33+
error: 'NotFound',
34+
message: t('messageGroupChatNotFound'),
35+
});
36+
});
37+
38+
it('likes a message', async () => {
39+
const receiver = await generateUser();
40+
41+
const sentMessageResult = await userToSendMessage.post('/members/send-private-message', {
42+
message: 'some message :)',
43+
toUserId: receiver._id,
44+
});
45+
46+
const { uniqueMessageId } = sentMessageResult.message;
47+
48+
const likeResult = await receiver.post(getLikeUrl(uniqueMessageId));
49+
expect(likeResult.likes[receiver._id]).to.equal(true);
50+
51+
const senderMessages = await userToSendMessage.get('/inbox/messages');
52+
53+
expectMessagesLikeStatus(senderMessages, uniqueMessageId, receiver._id, true);
54+
55+
const receiversMessages = await receiver.get('/inbox/messages');
56+
57+
expectMessagesLikeStatus(receiversMessages, uniqueMessageId, receiver._id, true);
58+
});
59+
60+
it('allows a user to like their own private message', async () => {
61+
const receiver = await generateUser();
62+
63+
const sentMessageResult = await userToSendMessage.post('/members/send-private-message', {
64+
message: 'some message :)',
65+
toUserId: receiver._id,
66+
});
67+
68+
const { uniqueMessageId } = sentMessageResult.message;
69+
70+
const likeResult = await userToSendMessage.post(getLikeUrl(uniqueMessageId));
71+
expect(likeResult.likes[userToSendMessage._id]).to.equal(true);
72+
73+
const messages = await userToSendMessage.get('/inbox/messages');
74+
expectMessagesLikeStatus(messages, uniqueMessageId, userToSendMessage._id, true);
75+
76+
const receiversMessages = await receiver.get('/inbox/messages');
77+
78+
expectMessagesLikeStatus(receiversMessages, uniqueMessageId, userToSendMessage._id, true);
79+
});
80+
81+
it('unlikes a message', async () => {
82+
const receiver = await generateUser();
83+
84+
const sentMessageResult = await userToSendMessage.post('/members/send-private-message', {
85+
message: 'some message :)',
86+
toUserId: receiver._id,
87+
});
88+
89+
const { uniqueMessageId } = sentMessageResult.message;
90+
91+
const likeResult = await receiver.post(getLikeUrl(uniqueMessageId));
92+
93+
expect(likeResult.likes[receiver._id]).to.equal(true);
94+
95+
const unlikeResult = await receiver.post(getLikeUrl(uniqueMessageId));
96+
97+
expect(unlikeResult.likes[receiver._id]).to.equal(false);
98+
99+
const messages = await userToSendMessage.get('/inbox/messages');
100+
101+
const messageToCheck = find(messages, { id: sentMessageResult.message.id });
102+
expect(messageToCheck.likes[receiver._id]).to.equal(false);
103+
});
104+
});

Diff for: website/client/.eslintrc.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ module.exports = {
77
extends: [
88
'habitrpg/lib/vue',
99
],
10-
ignorePatterns: ['dist/', 'node_modules/'],
10+
ignorePatterns: ['dist/', 'node_modules/', '*.d.ts'],
1111
rules: {
1212
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
1313
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',

Diff for: website/client/src/assets/scss/button.scss

+11-2
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,7 @@
101101

102102
.btn-secondary,
103103
.dropdown > .btn-secondary.dropdown-toggle:not(.btn-success),
104-
.show > .btn-secondary.dropdown-toggle:not(.btn-success)
105-
{
104+
.show > .btn-secondary.dropdown-toggle:not(.btn-success) {
106105
background: $white;
107106
border: 2px solid transparent;
108107
color: $gray-50;
@@ -298,6 +297,16 @@
298297
box-shadow: none;
299298
}
300299

300+
.btn-flat,
301+
.dropdown > .btn-flat.dropdown-toggle:not(.btn-success),
302+
.show > .btn-flat.dropdown-toggle:not(.btn-success) {
303+
&.with-icon {
304+
.svg-icon.color {
305+
color: var(--icon-color);
306+
}
307+
}
308+
}
309+
301310
.btn-cancel {
302311
color: $blue-10;
303312
}

Diff for: website/client/src/assets/scss/dropdown.scss

+9-2
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,12 @@
3838
border-radius: 2px;
3939
box-shadow: 0 3px 6px 0 rgba($black, 0.16), 0 3px 6px 0 rgba($black, 0.24);
4040
padding: 0;
41+
}
4142

43+
.no-min-width {
44+
.dropdown-menu {
45+
min-width: 0 !important;
46+
}
4247
}
4348

4449
// shared dropdown-item styles
@@ -54,6 +59,8 @@
5459
color: $gray-50 !important;
5560
cursor: pointer;
5661

62+
--dropdown-item-hover-icon-color: #{$gray-200};
63+
5764
&:focus {
5865
outline: none;
5966
background-color: inherit;
@@ -88,7 +95,7 @@
8895

8996
&:not(:hover) {
9097
.with-icon .svg-icon {
91-
color: $gray-200;
98+
color: var(dropdown-item-hover-icon-color);
9299
}
93100
}
94101
}
@@ -151,7 +158,7 @@
151158

152159
// selectList.vue items sizing
153160
.selectListItem .dropdown-item {
154-
padding: 0.25rem 0.75rem;
161+
padding: 0.25rem 1rem 0.25rem 0.75rem;
155162
height: 32px;
156163

157164
&:active, &:hover, &:focus, &.active {

0 commit comments

Comments
 (0)