2017-12-20 18:27:21 +00:00
< template lang = "pug" >
div
. mentioned - icon ( v - if = 'isUserMentioned' )
. message - hidden ( v - if = 'msg.flagCount === 1 && user.contributor.admin' ) Message flagged once , not hidden
. message - hidden ( v - if = 'msg.flagCount > 1 && user.contributor.admin' ) Message hidden
. card - body
2019-02-07 16:25:30 +00:00
user - link ( : userId = "msg.uuid" , : name = "msg.user" , : backer = "msg.backer" , : contributor = "msg.contributor" )
2018-10-19 21:20:13 +00:00
p . time
2018-10-17 23:28:58 +00:00
span . mr - 1 ( v - if = "msg.username" ) @ { { msg . username } }
span . mr - 1 ( v - if = "msg.username" ) •
2018-11-26 09:45:42 +00:00
span ( v - b - tooltip = "" , : title = "msg.timestamp | date" ) { { msg . timestamp | timeAgo } } & nbsp ;
span ( v - if = "msg.client && user.contributor.level >= 4" ) ( { { msg . client } } )
2018-11-26 14:47:22 +00:00
. text ( v - html = 'atHighlight(parseMarkdown(msg.text))' , ref = 'markdownContainer' )
2018-10-17 17:57:57 +00:00
hr
. d - flex ( v - if = 'msg.id' )
. action . d - flex . align - items - center ( v - if = '!inbox' , @ click = 'copyAsTodo(msg)' )
. svg - icon ( v - html = "icons.copy" )
div { { $t ( 'copyAsTodo' ) } }
. action . d - flex . align - items - center ( v - if = '!inbox && user.flags.communityGuidelinesAccepted && msg.uuid !== "system"' , @ click = 'report(msg)' )
. svg - icon ( v - html = "icons.report" )
div { { $t ( 'report' ) } }
// @TODO make flagging/reporting work in the inbox. NOTE: it must work even if the communityGuidelines are not accepted and it MUST work for messages that you have SENT as well as received. -- Alys
. action . d - flex . align - items - center ( v - if = 'msg.uuid === user._id || inbox || user.contributor.admin' , @ click = 'remove()' )
. svg - icon ( v - html = "icons.delete" )
| { { $t ( 'delete' ) } }
2018-11-03 18:16:32 +00:00
. ml - auto . d - flex ( v - b - tooltip = "{title: likeTooltip(msg.likes[user._id])}" , v - if = '!inbox' )
2018-10-17 23:28:58 +00:00
. action . d - flex . align - items - center . mr - 0 ( @ click = 'like()' , v - if = 'likeCount > 0' , : class = '{active: msg.likes[user._id]}' )
2018-11-03 18:16:32 +00:00
. svg - icon ( v - html = "icons.liked" , : title = '$t("liked")' )
2018-10-17 23:28:58 +00:00
| + { { likeCount } }
. action . d - flex . align - items - center . mr - 0 ( @ click = 'like()' , v - if = 'likeCount === 0' , : class = '{active: msg.likes[user._id]}' )
2018-11-03 18:16:32 +00:00
. svg - icon ( v - html = "icons.like" , : title = '$t("like")' )
2018-08-19 02:08:32 +00:00
span ( v - if = '!msg.likes[user._id]' ) { { $t ( 'like' ) } }
2017-12-20 18:27:21 +00:00
< / template >
2018-10-17 17:57:57 +00:00
< style lang = "scss" >
. at - highlight {
background - color : rgba ( 213 , 200 , 255 , 0.32 ) ;
padding : 0.1 rem ;
}
2018-11-15 21:58:07 +00:00
. at - text {
color : # 6133 b4 ;
}
2018-10-17 17:57:57 +00:00
< / style >
2017-12-20 18:27:21 +00:00
< style lang = "scss" scoped >
2018-10-17 23:28:58 +00:00
@ import '~client/assets/scss/colors.scss' ;
2017-12-20 18:27:21 +00:00
. mentioned - icon {
width : 16 px ;
height : 16 px ;
border - radius : 50 % ;
background - color : # bda8ff ;
box - shadow : 0 1 px 1 px 0 rgba ( 26 , 24 , 29 , 0.12 ) ;
position : absolute ;
right : - .5 em ;
top : - .5 em ;
}
2018-01-11 18:04:07 +00:00
. message - hidden {
2017-12-20 18:27:21 +00:00
margin - left : 1.5 em ;
margin - top : 1 em ;
color : red ;
}
2018-10-17 17:57:57 +00:00
hr {
margin - bottom : 0.5 rem ;
margin - top : 0.5 rem ;
}
2017-12-20 18:27:21 +00:00
. card - body {
2018-10-19 21:20:13 +00:00
padding : 0.75 rem 1.25 rem 0.75 rem 1.25 rem ;
2018-10-17 17:57:57 +00:00
2017-12-20 18:27:21 +00:00
. time {
font - size : 12 px ;
color : # 878190 ;
2018-10-17 17:57:57 +00:00
margin - bottom : 0.5 rem ;
2017-12-20 18:27:21 +00:00
}
. text {
font - size : 14 px ;
color : # 4 e4a57 ;
text - align : left ! important ;
2018-10-22 21:29:47 +00:00
min - height : 0 rem ;
margin - bottom : - 0.5 rem ;
2017-12-20 18:27:21 +00:00
}
}
. action {
display : inline - block ;
color : # 878190 ;
margin - right : 1 em ;
2018-10-17 17:57:57 +00:00
font - size : 12 px ;
2017-12-20 18:27:21 +00:00
2018-10-17 23:28:58 +00:00
: hover {
cursor : pointer ;
}
2017-12-20 18:27:21 +00:00
2018-10-17 23:28:58 +00:00
. svg - icon {
color : # A5A1AC ;
margin - right : .2 em ;
width : 16 px ;
}
2017-12-20 18:27:21 +00:00
}
2018-10-17 23:28:58 +00:00
. active {
color : $purple - 300 ;
2017-12-20 18:27:21 +00:00
2018-10-17 23:28:58 +00:00
. svg - icon {
color : $purple - 400 ;
}
2017-12-20 18:27:21 +00:00
}
< / style >
< script >
import axios from 'axios' ;
import moment from 'moment' ;
import cloneDeep from 'lodash/cloneDeep' ;
import escapeRegExp from 'lodash/escapeRegExp' ;
2018-11-13 20:14:02 +00:00
import max from 'lodash/max' ;
2017-12-20 18:27:21 +00:00
2018-10-17 17:57:57 +00:00
import habiticaMarkdown from 'habitica-markdown' ;
2017-12-20 18:27:21 +00:00
import { mapState } from 'client/libs/store' ;
2019-02-07 16:25:30 +00:00
import userLink from '../userLink' ;
2018-08-30 19:52:37 +00:00
2017-12-20 18:27:21 +00:00
import deleteIcon from 'assets/svg/delete.svg' ;
import copyIcon from 'assets/svg/copy.svg' ;
import likeIcon from 'assets/svg/like.svg' ;
import likedIcon from 'assets/svg/liked.svg' ;
import reportIcon from 'assets/svg/report.svg' ;
2019-02-07 16:55:36 +00:00
import { highlightUsers } from '../../libs/highlightUsers' ;
2017-12-20 18:27:21 +00:00
export default {
props : [ 'msg' , 'inbox' , 'groupId' ] ,
2019-02-07 16:25:30 +00:00
components : { userLink } ,
2017-12-20 18:27:21 +00:00
data ( ) {
return {
icons : Object . freeze ( {
like : likeIcon ,
copy : copyIcon ,
report : reportIcon ,
delete : deleteIcon ,
liked : likedIcon ,
} ) ,
} ;
} ,
filters : {
timeAgo ( value ) {
return moment ( value ) . fromNow ( ) ;
} ,
date ( value ) {
2018-07-21 13:09:36 +00:00
// @TODO: Vue doesn't support this so we cant user preference
2017-12-20 18:27:21 +00:00
return moment ( value ) . toDate ( ) ;
} ,
} ,
computed : {
... mapState ( { user : 'user.data' } ) ,
isUserMentioned ( ) {
const message = this . msg ;
2018-11-13 20:14:02 +00:00
const user = this . user ;
2017-12-20 18:27:21 +00:00
if ( message . hasOwnProperty ( 'highlight' ) ) return message . highlight ;
message . highlight = false ;
2018-11-13 20:14:02 +00:00
const messageText = message . text . toLowerCase ( ) ;
const displayName = user . profile . name ;
const username = user . auth . local && user . auth . local . username ;
const mentioned = max ( [ messageText . indexOf ( username . toLowerCase ( ) ) , messageText . indexOf ( displayName . toLowerCase ( ) ) ] ) ;
2017-12-20 18:27:21 +00:00
if ( mentioned === - 1 ) return message . highlight ;
2018-11-13 20:14:02 +00:00
const escapedDisplayName = escapeRegExp ( displayName ) ;
const escapedUsername = escapeRegExp ( username ) ;
2018-11-14 22:31:35 +00:00
const pattern = ` @( ${ escapedUsername } | ${ escapedDisplayName } )( \\ b) ` ;
2018-11-13 20:14:02 +00:00
const precedingChar = messageText . substring ( mentioned - 1 , mentioned ) ;
if ( mentioned === 0 || precedingChar . trim ( ) === '' || precedingChar === '@' ) {
2017-12-20 18:27:21 +00:00
let regex = new RegExp ( pattern , 'i' ) ;
2018-11-13 20:14:02 +00:00
message . highlight = regex . test ( messageText ) ;
2017-12-20 18:27:21 +00:00
}
return message . highlight ;
} ,
likeCount ( ) {
const message = this . msg ;
if ( ! message . likes ) return 0 ;
let likeCount = 0 ;
for ( let key in message . likes ) {
let like = message . likes [ key ] ;
if ( like ) likeCount += 1 ;
}
return likeCount ;
} ,
} ,
2018-11-26 14:47:22 +00:00
mounted ( ) {
const links = this . $refs . markdownContainer . getElementsByTagName ( 'a' ) ;
2018-11-27 14:39:59 +00:00
for ( let i = 0 ; i < links . length ; i ++ ) {
2018-11-26 14:47:22 +00:00
const link = links [ i ] ;
2019-02-05 13:39:57 +00:00
links [ i ] . onclick = ( ev ) => {
ev . preventDefault ( ) ;
2018-11-26 14:47:22 +00:00
this . $router . push ( { path : link . getAttribute ( 'href' ) } ) ;
} ;
}
} ,
2017-12-20 18:27:21 +00:00
methods : {
async like ( ) {
let message = cloneDeep ( this . msg ) ;
await this . $store . dispatch ( 'chat:like' , {
groupId : this . groupId ,
chatId : message . id ,
} ) ;
if ( ! message . likes [ this . user . _id ] ) {
message . likes [ this . user . _id ] = true ;
} else {
message . likes [ this . user . _id ] = ! message . likes [ this . user . _id ] ;
}
2018-03-31 11:20:41 +00:00
this . $emit ( 'message-liked' , message ) ;
2018-11-03 18:16:32 +00:00
this . $root . $emit ( 'bv::hide::tooltip' ) ;
} ,
likeTooltip ( likedStatus ) {
if ( ! likedStatus ) return this . $t ( 'like' ) ;
2017-12-20 18:27:21 +00:00
} ,
copyAsTodo ( message ) {
2018-02-05 16:43:00 +00:00
this . $root . $emit ( 'habitica::copy-as-todo' , message ) ;
2017-12-20 18:27:21 +00:00
} ,
async report ( ) {
this . $root . $emit ( 'habitica::report-chat' , {
message : this . msg ,
groupId : this . groupId ,
} ) ;
} ,
async remove ( ) {
if ( ! confirm ( this . $t ( 'areYouSureDeleteMessage' ) ) ) return ;
const message = this . msg ;
this . $emit ( 'message-removed' , message ) ;
if ( this . inbox ) {
2018-08-30 19:50:03 +00:00
await axios . delete ( ` /api/v4/inbox/messages/ ${ message . id } ` ) ;
2017-12-20 18:27:21 +00:00
return ;
}
await this . $store . dispatch ( 'chat:deleteChat' , {
groupId : this . groupId ,
chatId : message . id ,
} ) ;
} ,
2018-10-17 17:57:57 +00:00
atHighlight ( text ) {
2019-02-07 16:55:36 +00:00
return highlightUsers ( text , this . user . auth . local . username , this . user . profile . name ) ;
2018-10-17 17:57:57 +00:00
} ,
parseMarkdown ( text ) {
2018-11-26 14:47:22 +00:00
const mdText = habiticaMarkdown . render ( text ) ;
return mdText ;
2018-10-17 17:57:57 +00:00
} ,
2017-12-20 18:27:21 +00:00
} ,
} ;
< / script >