sender.vue 34 KB

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