basic.vue 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. <script>
  2. import { useScopedSlot } from "utils";
  3. export default {
  4. name: "lemonMessageBasic",
  5. inject: {
  6. IMUI: {
  7. from: "IMUI",
  8. default() {
  9. return this;
  10. },
  11. },
  12. },
  13. props: {
  14. contextmenu: Array,
  15. message: {
  16. type: Object,
  17. default: () => {
  18. return {};
  19. },
  20. },
  21. timeFormat: {
  22. type: Function,
  23. default: () => "",
  24. },
  25. reverse: Boolean,
  26. hideName: Boolean,
  27. hideTime: Boolean,
  28. },
  29. data() {
  30. return {};
  31. },
  32. render() {
  33. const { fromUser, status, sendTime } = this.message;
  34. const hideTitle = this.hideName == true && this.hideTime == true;
  35. return (
  36. <div
  37. class={[
  38. "lemon-message",
  39. `lemon-message--status-${status}`,
  40. {
  41. "lemon-message--reverse": this.reverse,
  42. "lemon-message--hide-title": hideTitle,
  43. },
  44. ]}
  45. >
  46. <div class="lemon-message__avatar">
  47. <lemon-avatar
  48. size={36}
  49. shape="square"
  50. src={fromUser.avatar}
  51. on-click={e => {
  52. this._emitClick(e, "avatar");
  53. }}
  54. />
  55. </div>
  56. <div class="lemon-message__inner">
  57. <div class="lemon-message__title">
  58. {this.hideName == false && (
  59. <span
  60. on-click={e => {
  61. this._emitClick(e, "displayName");
  62. }}
  63. >
  64. {fromUser.displayName}
  65. </span>
  66. )}
  67. {this.hideTime == false && (
  68. <span
  69. class="lemon-message__time"
  70. on-click={e => {
  71. this._emitClick(e, "sendTime");
  72. }}
  73. >
  74. {this.timeFormat(sendTime)}
  75. </span>
  76. )}
  77. </div>
  78. <div class="lemon-message__content-flex">
  79. <div
  80. v-lemon-contextmenu_message={this.IMUI.contextmenu}
  81. class="lemon-message__content"
  82. on-click={e => {
  83. this._emitClick(e, "content");
  84. }}
  85. >
  86. {useScopedSlot(this.$scopedSlots["content"], null, this.message)}
  87. </div>
  88. <div class="lemon-message__content-after">
  89. {useScopedSlot(
  90. this.IMUI.$scopedSlots["message-after"],
  91. null,
  92. this.message,
  93. )}
  94. </div>
  95. <div
  96. class="lemon-message__status"
  97. on-click={e => {
  98. this._emitClick(e, "status");
  99. }}
  100. >
  101. <i class="lemon-icon-loading lemonani-spin" />
  102. <i
  103. class="lemon-icon-prompt"
  104. title="重发消息"
  105. style={{
  106. color: "#ff2525",
  107. cursor: "pointer",
  108. }}
  109. />
  110. </div>
  111. </div>
  112. </div>
  113. </div>
  114. );
  115. },
  116. created() {},
  117. mounted() {},
  118. computed: {},
  119. watch: {},
  120. methods: {
  121. _emitClick(e, key) {
  122. this.IMUI.$emit("message-click", e, key, this.message, this.IMUI);
  123. },
  124. },
  125. };
  126. </script>
  127. <style lang="stylus">
  128. @import '~styles/utils/index'
  129. arrow()
  130. content ' '
  131. position absolute
  132. top 6px
  133. width 0
  134. height 0
  135. border 4px solid transparent
  136. +b(lemon-message)
  137. display flex
  138. padding 10px 0
  139. +e(time)
  140. color #b9b9b9
  141. padding 0 5px
  142. +e(inner)
  143. position relative
  144. +e(avatar)
  145. padding-right 10px
  146. user-select none
  147. .lemon-avatar
  148. cursor pointer
  149. +e(title)
  150. display flex
  151. font-size 12px
  152. line-height 16px
  153. height 16px
  154. padding-bottom 4px
  155. user-select none
  156. color #666
  157. +e(content-flex)
  158. display flex
  159. +e(content)
  160. font-size 14px
  161. line-height 20px
  162. padding 8px 10px
  163. background #fff
  164. border-radius 4px
  165. position relative
  166. margin 0
  167. img
  168. video
  169. background #e9e9e9
  170. height 100px
  171. &:before
  172. arrow()
  173. left -4px
  174. border-left none
  175. border-right-color #fff
  176. +e(content-after)
  177. display block
  178. width 48px
  179. height 36px
  180. padding-left 6px
  181. flex none
  182. font-size 12px
  183. color #aaa
  184. overflow hidden
  185. visibility hidden
  186. +e(status)
  187. position absolute
  188. top 23px
  189. right 20px
  190. color #aaa
  191. font-size 20px
  192. .lemon-icon-loading
  193. .lemon-icon-prompt
  194. display none
  195. +m(status-going)
  196. .lemon-icon-loading
  197. display inline-block
  198. +m(status-failed)
  199. .lemon-icon-prompt
  200. display inline-block
  201. +m(status-succeed)
  202. +e(content-after)
  203. visibility visible
  204. +m(reverse)
  205. flex-direction row-reverse
  206. +e(content-flex)
  207. flex-direction row-reverse
  208. +e(content-after)
  209. padding-right 6px
  210. padding-left 0
  211. text-align right
  212. +e(title)
  213. flex-direction row-reverse
  214. +e(status)
  215. left 26px
  216. right auto
  217. +e(content)
  218. background #35d863
  219. &:before
  220. arrow()
  221. left auto
  222. right -4px
  223. border-right none
  224. border-left-color #35d863
  225. +e(title)
  226. text-align right
  227. +e(avatar)
  228. padding-right 0
  229. padding-left 10px
  230. +m(hide-title)
  231. +e(avatar)
  232. padding-top 10px
  233. +e(status)
  234. top 14px
  235. +e(content)
  236. position relative
  237. top -10px
  238. &:before
  239. top 14px
  240. </style>