sender.vue 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985
  1. <template>
  2. <view>
  3. <view v-if="showPanel" style="height:75px;display: block;">
  4. </view>
  5. <view class="v-sender" id="v-send">
  6. <view class="v-sender__control v-sender__control_t" v-if="qute && qute.id && !voice">
  7. <!-- #ifndef H5 -->
  8. <view class="emoji" style="width: 64rpx;">
  9. </view>
  10. <!-- #endif -->
  11. <!-- 引用 -->
  12. <view class=" textarea qute-wrap">
  13. <!-- 文本 -->
  14. <template v-if="qute.message.type == 'text'">
  15. <!-- @文本 -->
  16. <view class="content" v-if="qute.message.content.type && qute.message.content.type == 'remind'">
  17. {{qute.sender.nickname}}: <text v-html="qute.message.qute"></text>
  18. </view>
  19. <!-- 纯文本 -->
  20. <view class="content" v-else>
  21. {{qute.sender.nickname}}:{{qute.message && qute.message.qute ? qute.message.qute: ''}}
  22. </view>
  23. </template>
  24. <!-- -->
  25. <view class="content" v-if="qute.message.type == 'emotion'">
  26. {{qute.sender.nickname}}:
  27. <block v-for="(m1,index1) in qute.message.face" :key="index1">
  28. <block v-if="m1.type=='img'">
  29. <image :src="m1.content" class="emotion"></image>
  30. </block>
  31. <block v-else>{{m1.content}}</block>
  32. </block>
  33. </view>
  34. <view class="content" v-if="qute.message.type == 'image'">
  35. {{qute.sender.nickname}}:[图片]
  36. </view>
  37. <image src="../static/img/del.png" mode="" @click="clearQute"></image>
  38. </view>
  39. </view>
  40. <view class="v-sender__control">
  41. <!-- #ifndef H5 -->
  42. <view class="emoji" @tap="sendVoice">
  43. <text v-if="!voice && !noSpeaking" class="n-icon n-icon-voice"></text>
  44. <text v-else class="n-icon n-icon-keyboard"></text>
  45. </view>
  46. <!-- #endif -->
  47. <block v-if="noSpeaking">
  48. <view class="falseinput"
  49. style="text-align: center;color: #999;margin-left: 16upx;margin-right: 20upx;margin-left:10px;">
  50. {{speaking_tips}}
  51. </view>
  52. </block>
  53. <block v-else>
  54. <textarea v-if="!voice" ref="shuru" id="sendbox" maxlength="99999999999" auto-height="true"
  55. :class="{'textarea':true,'input':input_value && !voice}" v-model="input_value"
  56. type="text" @input="listen('input', $event.detail.value)" @confirm="set_focos()"
  57. @tap="sendertap();" confirm-type='发送' adjust-position="ture" confirm-hold="true"
  58. cursor-spacing="15" style="overflow-y: auto;" :focus='focusState'>
  59. </textarea>
  60. <view v-if="voice" :class="{'falseinput':true,'press':setting}"
  61. style="text-align: center;color: #222;margin-right: 20upx;" @touchstart="startVoice"
  62. @touchend="endVoice" @touchmove.stop.prevent="voiceIng" @touchcancel="voiceCancel">{{voiceTis}}
  63. </view>
  64. <!-- 图片/表情 -->
  65. <view class="emoji" @tap="showemoji();" v-if="!emoji"><text class="n-icon n-icon-face"></text>
  66. </view>
  67. <view class="emoji" @tap="hideemoji();" v-if="emoji"><text class="n-icon n-icon-keyboard"></text>
  68. </view>
  69. <view class="btn sendbtn" v-if="input_value && !voice" @touchend.prevent="tapsender">发送</view>
  70. <view class="bigbox3" v-if="!input_value && !voice">
  71. <view class="emoji" @tap="show_panel();" v-if="!showPanel&&!input_value"><text>&#xe634;</text>
  72. </view>
  73. <view class="emoji" @tap="hide_panel();" v-else-if="showPanel&&!input_value">
  74. <text>&#xe603;</text>
  75. </view>
  76. </view>
  77. </block>
  78. </view>
  79. <view class="record" :class="setting?'':'hidden'">
  80. <view class="ing" :class="willStop?'hidden':''">
  81. <view class="icon luyin2"></view>
  82. </view>
  83. <view class="cancel" :class="willStop?'':'hidden'">
  84. <view class="icon chehui"></view>
  85. </view>
  86. <view class="tis" :class="willStop?'change':''">{{recordTis}}</view>
  87. </view>
  88. <view v-if="emoji" class="face_box">
  89. <view style="width: 100%;">
  90. <view class="emotion-box" style="height:200px">
  91. <view class="emotion-box-line" v-for="(line, i) in lists" :key="i">
  92. <view class="emotion-item" v-for="(item, index) in line" :key="index"
  93. @click="handleEmotion(item)">
  94. <image :src="'/static/emoji/'+item.name+'.gif'" style="width: 50rpx;height: 50rpx;">
  95. </image>
  96. </view>
  97. </view>
  98. </view>
  99. </view>
  100. </view>
  101. <view v-if="showPanel" class="v-sender__panel">
  102. <view @click="sendImg('album')">
  103. <view class="icons"><text class="n-icon n-icon-image"></text></view>
  104. <view>图片</view>
  105. </view>
  106. <view class="box" @click="sendImg('camera')">
  107. <view class="icons"><text class="n-icon n-icon-paizhao"></text></view>
  108. <view>拍照</view>
  109. </view>
  110. <view class="box" @click="sendVedio('album')">
  111. <view class="icons">
  112. <image src="../static/img/vedio.png"></image>
  113. </view>
  114. <view>视频</view>
  115. </view>
  116. <view class="box" @click="sendVedio('camera')">
  117. <view class="icons">
  118. <image src="../static/img/camera.png"></image>
  119. </view>
  120. <view>录像</view>
  121. </view>
  122. <!-- <view class="box" @click="sendRedpactet()">
  123. <view class="icons"><image src="../static/img/redpacket.png" style="width: 26px;" ></image></view>
  124. <view>红包</view>
  125. </view> -->
  126. </view>
  127. </view>
  128. </view>
  129. </template>
  130. <script>
  131. const recorderManager = uni.getRecorderManager();
  132. const {
  133. windowWidth,
  134. windowHeight
  135. } = uni.getSystemInfoSync();
  136. import helper from "../library/helper.js"
  137. import api from "../library/index.js"
  138. import action from "../library/action.js"
  139. export default {
  140. name: 'v-sender',
  141. props: {
  142. placeholder: {
  143. type: String,
  144. default: '说点什么吧'
  145. },
  146. value: {
  147. type: String,
  148. default: ''
  149. },
  150. noSpeaking: {
  151. type: Boolean,
  152. default: false
  153. },
  154. speaking_tips: {
  155. },
  156. forbidRedpack: {
  157. type: Boolean,
  158. default: false
  159. },
  160. showboard: {
  161. type: Boolean,
  162. default: false
  163. },
  164. groupid: {
  165. type: [Number, String],
  166. default: 0
  167. },
  168. isgroup: {
  169. default: 0
  170. },
  171. sendtype: {
  172. type: [Number, String],
  173. default: 'text'
  174. }
  175. },
  176. data() {
  177. return {
  178. focusState: false,
  179. qute: {},
  180. showPanel: false,
  181. showPacket: false,
  182. voice: false,
  183. text: 'uni-app',
  184. voicePath: '',
  185. setting: false,
  186. emoji: false,
  187. faceImg: {},
  188. swipers: [],
  189. voiceTis: '按住 说话',
  190. recordTis: "手指上滑 取消发送",
  191. recording: false,
  192. willStop: false,
  193. initPoint: {
  194. identifier: 0,
  195. Y: 0
  196. },
  197. recordTimer: null,
  198. recordLength: 0,
  199. mids: {},
  200. uploadnum: 0,
  201. starttime: 0,
  202. endtime: 0,
  203. voice_mid: '',
  204. focus: false,
  205. input_value: '',
  206. area_value: '',
  207. inputclass: 'textarea',
  208. sendtime: 0,
  209. keyboardheight: 0,
  210. borderheight: 0,
  211. user: uni.getStorageSync('userInfo'),
  212. list: [
  213. ['微笑', '撇嘴', '色', '发呆', '得意', '流泪', '害羞', '闭嘴'],
  214. ['睡', '大哭', '尴尬', '发怒', '调皮', '呲牙', '惊讶', '难过'],
  215. ['酷', '冷汗', '抓狂', '吐', '偷笑', '可爱', '白眼', '傲慢'],
  216. ['饥饿', '困', '惊恐', '流汗', '憨笑', '大兵', '奋斗', '咒骂'],
  217. ['疑问', '嘘', '晕', '折磨', '衰', '骷髅', '敲打', '再见'],
  218. ['擦汗', '抠鼻', '鼓掌', '糗大了', '坏笑', '左哼哼', '右哼哼', '哈欠'],
  219. ['鄙视', '委屈', '快哭了', '阴险', '亲亲', '吓', '可怜', '菜刀'],
  220. ['西瓜', '啤酒', '篮球', '乒乓', '咖啡', '饭', '猪头', '玫瑰', ],
  221. ['凋谢', '示爱', '爱心', '心碎', '蛋糕', '闪电', '炸弹', '刀'],
  222. ['足球', '瓢虫', '便便', '月亮', '太阳', '礼物', '拥抱', '强'],
  223. ['弱', '握手', '胜利', '抱拳', '勾引', '拳头', '差劲', '爱你'],
  224. ['NO', 'OK', '爱情', '飞吻', '跳跳', '发抖', '怄火', '转圈'],
  225. ['磕头', '回头', '跳绳', '挥手', '激动', '闭嘴', '笑哭', '吐舌'],
  226. ['耶', '跳舞', '恐惧', '失望', '脸红', '无语', '奸笑', '嘿哈'],
  227. ['鬼混', '福', '合十', '强壮', '红包', '发财', '庆祝', '礼物']
  228. ],
  229. reg: /\S{1,3}/gi,
  230. lists: [],
  231. listss: []
  232. }
  233. },
  234. mounted() {
  235. let that = this;
  236. // #ifdef APP-PLUS
  237. recorderManager.onStart((e) => {
  238. this.recordBegin(e);
  239. })
  240. recorderManager.onStop(res => {
  241. this.recordStop(res);
  242. });
  243. // #endif
  244. var value = '';
  245. this.list = this.list.map((line, index) => {
  246. this.listss = [];
  247. line = line.map((item, idx) => {
  248. value = item;
  249. item = item.replace(/\S{1,3}/gi, this.emotion(item));
  250. this.listss.push({
  251. "name": item,
  252. "index": index,
  253. "value": value,
  254. "idx": idx
  255. })
  256. return item;
  257. })
  258. this.lists.push(this.listss);
  259. return line;
  260. })
  261. },
  262. computed: {
  263. sendShowing() {
  264. return this.value.length > 0
  265. },
  266. },
  267. methods: {
  268. showCall(val) {
  269. val = val + ''
  270. let str = ''
  271. if(val) {
  272. str = val.replace(/<span.*?>|<\/span>/g, "")
  273. }
  274. return str
  275. },
  276. // 清理引用
  277. clearQute() {
  278. this.qute = {}
  279. // 清理父的qute
  280. this.$emit('clearQute')
  281. },
  282. // 保存引用
  283. setQute(item) {
  284. let that = this
  285. that.qute = item
  286. console.log('that.qute',that.qute);
  287. let data = this.$refs.shuru
  288. that.focusState = false
  289. this.$nextTick(()=> {
  290. that.focusState = true
  291. })
  292. },
  293. emotion(res) {
  294. //let word = res.replace(/\#|\;/gi,'')
  295. const list = ['微笑', '撇嘴', '色', '发呆', '得意', '流泪', '害羞', '闭嘴', '睡', '大哭', '尴尬', '发怒', '调皮', '呲牙', '惊讶',
  296. '难过', '酷', '冷汗', '抓狂', '吐', '偷笑', '可爱', '白眼', '傲慢', '饥饿', '困', '惊恐', '流汗', '憨笑', '大兵', '奋斗',
  297. '咒骂', '疑问', '嘘', '晕', '折磨', '衰', '骷髅', '敲打', '再见', '擦汗', '抠鼻', '鼓掌', '糗大了', '坏笑', '左哼哼', '右哼哼',
  298. '哈欠', '鄙视', '委屈', '快哭了', '阴险', '亲亲', '吓', '可怜', '菜刀', '西瓜', '啤酒', '篮球', '乒乓', '咖啡', '饭', '猪头',
  299. '玫瑰', '凋谢', '示爱', '爱心', '心碎', '蛋糕', '闪电', '炸弹', '刀', '足球', '瓢虫', '便便', '月亮', '太阳', '礼物', '拥抱',
  300. '强', '弱', '握手', '胜利', '抱拳', '勾引', '拳头', '差劲', '爱你', 'NO', 'OK', '爱情', '飞吻', '跳跳', '发抖', '怄火',
  301. '转圈', '磕头', '回头', '跳绳', '挥手', '激动', '闭嘴', '笑哭', '吐舌', '耶', '跳舞', '恐惧', '失望', '脸红', '无语', '奸笑',
  302. '嘿哈', '鬼混', '福', '合十', '强壮', '红包', '发财', '庆祝', '礼物'
  303. ]
  304. let index = list.indexOf(res)
  305. var index1 = index + 100;
  306. return index1
  307. },
  308. showemoji() {
  309. this.showPanel = false;
  310. this.emoji = true;
  311. // this.setChatHeight();
  312. },
  313. hideemoji() {
  314. this.showPanel = false;
  315. this.emoji = false;
  316. // this.setChatHeight();
  317. },
  318. show_panel() {
  319. this.showPanel = true;
  320. this.emoji = false;
  321. this.setChatHeight();
  322. },
  323. hide_panel() {
  324. this.showPanel = false;
  325. this.emoji = false;
  326. this.setChatHeight();
  327. },
  328. setChatHeight() {
  329. //
  330. // console.log(this.sendHeight);
  331. var that = this;
  332. setTimeout(() => {
  333. var that = this;
  334. var query = uni.createSelectorQuery(); // 这里要加上select
  335. query.in(that).select('#v-send').boundingClientRect(res => {
  336. var hh = (parseInt(res.height) - 60);
  337. this.$emit("senderheight", hh);
  338. }).exec();
  339. }, 100);
  340. },
  341. sendVedio(type) {
  342. let that = this
  343. uni.chooseVideo({
  344. sourceType: [type],
  345. maxDuration: 15,
  346. compressed: false,
  347. success(re) {
  348. // console.log(re.tempFilePath);
  349. //console.log(re.tempFilePaths[0]);
  350. that.sendertap();
  351. var mids = 'm' + Math.random().toString(36).substring(2);
  352. var duration = re.duration;
  353. that.$emit('sendVedio', {
  354. mid: mids,
  355. src: re.tempFilePath,
  356. time: duration
  357. });
  358. var _that = that;
  359. helper.uploadFiles([re.tempFilePath], 'Vedio', {
  360. type: 'vedio'
  361. }).then(res => {
  362. that.$emit('sendVedio', {
  363. mid: mids,
  364. src: res,
  365. time: duration
  366. });
  367. });
  368. }
  369. })
  370. },
  371. sendImg(type) {
  372. let that = this
  373. uni.chooseImage({
  374. sourceType: [type],
  375. sizeType: ['original', 'compressed'],
  376. success(re) {
  377. //console.log(re.tempFilePaths.length);
  378. //console.log(re.tempFilePaths[0]);
  379. that.sendertap();
  380. that.uploadnum = 0;
  381. for (var i = 0; i < re.tempFilePaths.length; i++) {
  382. that.mids[i] = 'm' + Math.random().toString(36).substring(2);
  383. // that.$emit('sendImage', {mid:that.mids[i],src: re.tempFilePaths[i]});
  384. var _that = that;
  385. // console.log(re.tempFilePaths[i]);
  386. helper.uploadFiles([re.tempFilePaths[i]], 'images', {
  387. type: 'images'
  388. }).then(res => {
  389. that.$emit('sendImage', {
  390. mid: _that.mids[that.uploadnum],
  391. src: res
  392. });
  393. });
  394. }
  395. }
  396. })
  397. },
  398. sendRedpactet() {
  399. if (this.user.banknum < 1) {
  400. uni.showModal({
  401. title: '提示',
  402. content: "绑定银行卡后才可以发送红包",
  403. showCancel: true,
  404. cancelText: '关闭',
  405. confirmText: '立即绑定',
  406. success: res => {
  407. if (res.confirm) {
  408. uni.navigateTo({
  409. url: "/pages/mine/bank"
  410. })
  411. }
  412. }
  413. });
  414. return false;
  415. } else {
  416. uni.navigateTo({
  417. url: '../friend/readpacket?isgroup=' + this.isgroup + '&id=' + this.groupid
  418. })
  419. }
  420. this.hide_panel();
  421. },
  422. listen(name, eventOrValue) {
  423. this.$emit(name, eventOrValue);
  424. this.focus = false;
  425. },
  426. set_focos() {
  427. if (this.focus == false) this.focus = true;
  428. },
  429. getfocus(detail) {
  430. this.boardheight = detail.height;
  431. // #ifdef APP-PLUS
  432. if (plus.os.name == 'Android') this.$emit("keyboardheight", detail.height);
  433. // #endif
  434. },
  435. unfocus() {
  436. this.boardheight = 0;
  437. // console.log('sender失去焦点')
  438. this.$emit("keyboardheight", 0);
  439. },
  440. unfocus1() {
  441. // console.log('box失去焦点')
  442. this.$emit("keyboardheight", 0);
  443. },
  444. sendertap() {
  445. this.showPanel = false;
  446. this.emoji = false;
  447. // z uni.hideKeyboard();
  448. },
  449. setinputvalue(e) {
  450. this.input_value = this.input_value + e + ' ';
  451. this.$emit('input', this.input_value);
  452. },
  453. istap() {
  454. },
  455. tapsender() {
  456. //this.inputclass='textarea sending'
  457. if (this.input_value != '') {
  458. var that = this;
  459. // setTimeout(function(){that.$emit('send',that.$event);},1000)
  460. that.$emit('send', that.$event);
  461. this.area_value = '';
  462. this.input_value = '';
  463. //that.$emit("senderheight",0);
  464. //this.keyboardheight=this.boardheight;
  465. // this.$emit("senderheight",300);
  466. if (this.sendtype != 'text') {
  467. this.hideemoji();
  468. this.hide_panel();
  469. }
  470. // #ifdef APP-PLUS
  471. //if(plus.os.name=="iOS") uni.hideKeyboard();
  472. // #endif
  473. }
  474. },
  475. listen1(e) {
  476. // console.log(e);
  477. this.input_value = e;
  478. this.listen('input', e);
  479. // console.log(e);
  480. },
  481. clickbox(e) {
  482. var x = e.touches[0].clientX;
  483. var y = e.touches[0].clientY;
  484. // console.log( windowWidth-x, windowHeight-y)
  485. if (windowWidth - x < 65) this.tapsender();
  486. },
  487. startVoice(e) {
  488. this.setting = true;
  489. this.willStop = false;
  490. this.voiceTis = '手指上滑 取消发送'
  491. recorderManager.start({
  492. format: 'mp3',
  493. numberOfChannels: 2,
  494. duration: 6000
  495. });
  496. this.starttime = new Date().getTime();
  497. this.initPoint.Y = e.touches[0].clientY;
  498. this.initPoint.identifier = e.touches[0].identifier;
  499. console.log('start');
  500. },
  501. //录音开始UI效果
  502. recordBegin(e) {
  503. /** 暂停语音播放 */
  504. console.log('录音开始UI效果');
  505. recorderManager.pause();
  506. this.setting = true;
  507. this.voiceTis = '松开 结束';
  508. this.recordLength = 0;
  509. this.recordTimer = setInterval(() => {
  510. this.recordLength++;
  511. }, 1000)
  512. },
  513. //录音停止 上传到服务器
  514. recordStop(res) {
  515. var that = this;
  516. this.endtime = new Date().getTime();
  517. that.voicePath = res.tempFilePath;
  518. if (!this.willStop) {
  519. if (this.endtime - this.starttime < 1000) return that.$toast('时间太短了');
  520. var duration = (this.endtime - this.starttime) / 1000;
  521. this.voice_mid = 'm' + Math.random().toString(36).substring(2);
  522. that.$emit('face', {
  523. url: that.voicePath,
  524. time: duration.toFixed(2),
  525. mid: this.voice_mid
  526. })
  527. helper.uploadFiles([that.voicePath], 'audio', {
  528. type: 'audio'
  529. }).then(res => {
  530. that.$emit('face', {
  531. url: res,
  532. time: duration.toFixed(2),
  533. mid: this.voice_mid
  534. })
  535. });
  536. action.playVoice('/static/voice/voice.mp3');
  537. } else {
  538. console.log('取消发送录音');
  539. }
  540. },
  541. // 录音被打断
  542. voiceCancel() {
  543. this.setting = false;
  544. this.willStop = true; //不发送录音
  545. recorderManager.stop(); //录音结束
  546. this.voiceTis = '按住 说话';
  547. this.recordTis = '手指上滑 取消发送'
  548. },
  549. // 录音中(判断是否触发上滑取消发送)
  550. voiceIng(e) {
  551. if (!this.setting) {
  552. return;
  553. }
  554. let touche = e.touches[0];
  555. //上滑一个导航栏的高度触发上滑取消发送
  556. if (this.initPoint.Y - touche.clientY >= uni.upx2px(100)) {
  557. this.willStop = true;
  558. this.recordTis = '松开手指 取消发送'
  559. } else {
  560. this.willStop = false;
  561. this.recordTis = '手指上滑 取消发送'
  562. }
  563. },
  564. endVoice() {
  565. this.setting = false
  566. recorderManager.stop();
  567. this.voiceTis = '按住 说话';
  568. this.recordTis = '手指上滑 取消发送';
  569. },
  570. sendVoice() {
  571. this.voice = !this.voice;
  572. },
  573. getEmoji() {
  574. },
  575. sendEmoji(e) {
  576. //this.showPanel = false;
  577. this.emoji = false
  578. this.$emit('emoji', e)
  579. },
  580. handleEmotion(item) {
  581. var v = item.value;
  582. this.input_value += '[' + v + ']';
  583. this.area_value = this.input_value
  584. this.listen1(this.input_value);
  585. this.$emit('handleEmotion', this.input_value);
  586. },
  587. },
  588. created() {
  589. this.getEmoji()
  590. },
  591. onLoad() {
  592. },
  593. }
  594. </script>
  595. <style lang="scss" scoped>
  596. @import "@/static/css/chat/style.scss";
  597. $control-height: 120upx;
  598. $input-height: $control-height - $uni-spacing-col-base * 2;
  599. .face_box {
  600. position: fixed;
  601. bottom: 60px;
  602. ;
  603. left: 1px;
  604. width: calc(100% - 4px);
  605. z-index: 99;
  606. background-color: #fff;
  607. border: 1px #ddd solid;
  608. padding-top: 5px;
  609. ;
  610. border-top-right-radius: 5px;
  611. border-top-left-radius: 5px;
  612. }
  613. .faceImg {
  614. width: 100upx;
  615. flex-basis: 100upx;
  616. }
  617. .n-icon {
  618. font-size: 33px;
  619. line-height: 33px;
  620. color: #333;
  621. vertical-align: middle;
  622. }
  623. .icons {
  624. height: 70upx;
  625. line-height: 70upx;
  626. vertical-align: middle;
  627. }
  628. .icons image {
  629. width: 65upx;
  630. height: 55upx;
  631. vertical-align: middle;
  632. }
  633. .bigbox {
  634. position: fixed;
  635. bottom: 0px;
  636. left: 110upx;
  637. width: calc(100vw - 100upx);
  638. height: 120upx;
  639. line-height: 120upx;
  640. padding: 0px;
  641. z-index: 0;
  642. border: 0px #eee solid;
  643. color: transparent !important;
  644. }
  645. .bigbox2 {
  646. position: absolute;
  647. top: 10px;
  648. right: 80upx;
  649. width: 84upx;
  650. height: 120upx;
  651. line-height: 120upx;
  652. padding: 0px;
  653. z-index: 10;
  654. border: 0px #eee solid;
  655. }
  656. .bigbox3 {
  657. position: absolute;
  658. top: 10px;
  659. right: 0upx;
  660. width: 80upx;
  661. height: 120upx;
  662. line-height: 120upx;
  663. padding: 0px;
  664. z-index: 0;
  665. text-align: right;
  666. justify-content: right;
  667. border: 0px #eee solid;
  668. }
  669. .sending {
  670. color: transparent !important;
  671. }
  672. .v-sender {
  673. z-index: 99999999;
  674. position: fixed;
  675. bottom: 0;
  676. left: 0;
  677. width: 99vw;
  678. padding-left: 1vw;
  679. background-color: #fafafa;
  680. border-top: 1px solid #ddd;
  681. &__panel,
  682. &__control {
  683. position: relative;
  684. width: 100%;
  685. &::before {
  686. display: block;
  687. content: '\20';
  688. position: absolute;
  689. top: 0;
  690. left: 0;
  691. width: 100%;
  692. // background-color: #ddd;
  693. height: 1upx;
  694. transform: scaleY(0.5);
  695. }
  696. }
  697. &__panel {
  698. width: 100%;
  699. display: table;
  700. padding: 20upx 0;
  701. font-size: 28upx;
  702. background: #fafafa;
  703. >view {
  704. .n-icon {
  705. font-size: 33px;
  706. color: #999;
  707. }
  708. text-align: center;
  709. display: table-cell;
  710. }
  711. }
  712. &__control {
  713. height: $control-height;
  714. padding: $uni-spacing-col-base 0px $uni-spacing-col-base 0;
  715. &,
  716. .emoji,
  717. .btn {
  718. display: flex;
  719. flex-direction: row;
  720. flex-wrap: nowrap;
  721. align-items: center;
  722. box-sizing: border-box;
  723. }
  724. >.emoji,
  725. >.btn,
  726. >input {
  727. margin-left: $uni-spacing-row-base;
  728. }
  729. view {
  730. height: $input-height;
  731. flex-shrink: 0;
  732. }
  733. .emoji {
  734. font-size: 64upx;
  735. line-height: $input-height;
  736. }
  737. input,
  738. .falseinput {
  739. flex: 1;
  740. height: $input-height;
  741. border-radius: $uni-border-radius-base;
  742. box-sizing: border-box;
  743. background-color: #ccc;
  744. height: 68upx;
  745. line-height: 68upx;
  746. margin-left: 10px;
  747. ;
  748. }
  749. .falseinput.press {
  750. background-color: #666;
  751. color: #fff !important;
  752. }
  753. .btn {
  754. line-height: $input-height - 10upx;
  755. height: $input-height - 10upx;
  756. color: #fff;
  757. text-align: center;
  758. background-color: $uni-color-primary;
  759. }
  760. }
  761. &__control_t {
  762. height: 80upx;
  763. padding: 0;
  764. .qute-wrap {
  765. border: none;
  766. background-color: #eaeaea;
  767. height: 40upx;
  768. font-size: 26upx;
  769. color: #6d6d6d;
  770. display: flex;
  771. justify-content: space-between;
  772. flex-wrap: nowrap;
  773. .content {
  774. flex-grow: 1;
  775. text-overflow:ellipsis;
  776. white-space:nowrap;
  777. overflow:hidden;
  778. max-width: 90%;
  779. height: 45rpx;
  780. }
  781. image {
  782. flex-shrink: 0;
  783. width: 28upx;
  784. height: 28upx;
  785. }
  786. }
  787. }
  788. }
  789. .textarea,
  790. .textareas {
  791. font-size: 32upx;
  792. background: #fff;
  793. border: 1px solid #ddd;
  794. max-height: 80upx;
  795. min-height: 40upx;
  796. line-height: 40upx;
  797. padding: 12upx 10upx;
  798. border-radius: 3px;
  799. ;
  800. }
  801. .textarea {
  802. margin-left: 10px;
  803. /* #ifndef H5 */
  804. width: calc(100% - 290upx);
  805. /* #endif */
  806. /* #ifdef H5 */
  807. width: calc(100% - 210upx);
  808. /* #endif */
  809. }
  810. .textarea.input {
  811. /* #ifndef H5 */
  812. width: calc(100% - 360upx);
  813. /* #endif */
  814. /* #ifdef H5 */
  815. width: calc(100% - 280upx);
  816. /* #endif */
  817. }
  818. .sendbtn {
  819. margin-left: 16upx !important;
  820. padding: 0px 40upx !important;
  821. }
  822. .emotion-box {
  823. margin: 0 auto;
  824. width: calc(100% - 4px);
  825. box-sizing: border-box;
  826. padding: 2px;
  827. overflow: hidden;
  828. overflow-y: auto;
  829. }
  830. .emotion-box-line {
  831. display: flex;
  832. }
  833. .emotion-item {
  834. flex: 1;
  835. text-align: center;
  836. cursor: pointer;
  837. }
  838. </style>