增加右键菜单配置

增加setEditorValue、getEditorValue方法
修改updateContact传参
修复只选择表情发送按钮是灰色的问题
修复send之后toContactId丢失的问题
This commit is contained in:
fan
2021-01-30 21:03:15 +08:00
parent f56dc40075
commit 3603d0c03b
23 changed files with 825 additions and 184 deletions
+194 -56
View File
@@ -3187,6 +3187,13 @@ module.exports = {
};
/***/ }),
/***/ "8bbf":
/***/ (function(module, exports) {
module.exports = require("vue");
/***/ }),
/***/ "8e60":
@@ -5566,7 +5573,7 @@ var tabs_render, staticRenderFns
/* normalize component */
var component = normalizeComponent(
var tabs_component = normalizeComponent(
components_tabsvue_type_script_lang_js_,
tabs_render,
staticRenderFns,
@@ -5577,7 +5584,7 @@ var component = normalizeComponent(
)
/* harmony default export */ var tabs = (component.exports);
/* harmony default export */ var tabs = (tabs_component.exports);
// EXTERNAL MODULE: ./node_modules/regenerator-runtime/runtime.js
var runtime = __webpack_require__("96cf");
@@ -5712,7 +5719,7 @@ var triggerEvents = {
"style": "position:relative"
}, [h("transition", {
"attrs": {
"name": "slide-top"
"name": "lemon-slide-top"
}
}, [this.visible && h("div", {
"class": "lemon-popover",
@@ -6184,6 +6191,10 @@ function arrayIntersect(a, b) {
function clearHtml(str) {
return str.replace(/<.*?>/ig, "");
} //清除字符串内的所有HTML标签,除了IMG
function clearHtmlExcludeImg(str) {
return str.replace(/<(?!img).*?>/ig, "");
}
function error(text) {
throw new Error(text);
@@ -6249,6 +6260,14 @@ function generateUUID() {
/* harmony default export */ var contactvue_type_script_lang_js_ = ({
name: "LemonContact",
components: {},
inject: {
IMUI: {
from: 'IMUI',
default: function _default() {
return this;
}
}
},
data: function data() {
return {};
},
@@ -6283,24 +6302,16 @@ function generateUUID() {
watch: {},
methods: {
_renderInner: function _renderInner() {
var _this2 = this;
var h = this.$createElement;
var contact = this.contact;
return [h("lemon-badge", {
"attrs": {
"count": !this.simple ? contact.unread : 0,
"native-on-click": function nativeOnClick(e) {
return _this2._handleBubbleClick(e, contact);
}
"count": !this.simple ? contact.unread : 0
},
"class": "lemon-contact__avatar"
}, [h("lemon-avatar", {
"attrs": {
"size": 40,
"native-on-click": function nativeOnClick(e) {
return _this2._handleAvatarClick(e, contact);
},
"src": contact.avatar
}
})]), h("div", {
@@ -6321,14 +6332,6 @@ function generateUUID() {
},
_handleClick: function _handleClick(e, data) {
this.$emit("click", data);
},
_handleAvatarClick: function _handleAvatarClick(e, data) {
e.stopPropagation();
this.$emit("avatar-click", data);
},
_handleBubbleClick: function _handleBubbleClick(e, data) {
e.stopPropagation();
this.$emit("bubble-click", data);
}
}
});
@@ -6662,6 +6665,8 @@ var isInitTool = false;
exec("<img emoji-name=\"".concat(item.name, "\" src=\"").concat(item.src, "\"></img>"));
this._checkSubmitDisabled();
this._saveLastRange();
},
selectFile: function () {
@@ -6724,7 +6729,7 @@ var isInitTool = false;
return toEmojiName(this.$refs.textarea.innerHTML);
},
_checkSubmitDisabled: function _checkSubmitDisabled() {
this.submitDisabled = !this.$refs.textarea.innerText.trim();
this.submitDisabled = !clearHtmlExcludeImg(this.$refs.textarea.innerHTML.trim());
},
_handleSend: function _handleSend(e) {
var text = this.getFormatValue();
@@ -6748,6 +6753,11 @@ var isInitTool = false;
initEmoji: function initEmoji(data) {
emojiData = data;
this.$forceUpdate();
},
setValue: function setValue(val) {
this.$refs.textarea.innerHTML = val;
this._checkSubmitDisabled();
}
}
});
@@ -6777,6 +6787,86 @@ var editor_component = normalizeComponent(
)
/* harmony default export */ var editor = (editor_component.exports);
// EXTERNAL MODULE: external {"commonjs":"vue","commonjs2":"vue","root":"Vue"}
var external_commonjs_vue_commonjs2_vue_root_Vue_ = __webpack_require__("8bbf");
var external_commonjs_vue_commonjs2_vue_root_Vue_default = /*#__PURE__*/__webpack_require__.n(external_commonjs_vue_commonjs2_vue_root_Vue_);
// CONCATENATED MODULE: ./packages/directives/dropdown.js
var dropdown_popover;
var hidePopover = function hidePopover() {
if (dropdown_popover) dropdown_popover.style.display = 'none';
};
var showPopover = function showPopover() {
if (dropdown_popover) dropdown_popover.style.display = 'block';
};
document.addEventListener('click', function (e) {
hidePopover();
});
/* harmony default export */ var dropdown = ({
hide: hidePopover,
bind: function bind(el, binding, vnode) {
el.addEventListener('contextmenu', function (e) {
if (isEmpty(binding.value) || !Array.isArray(binding.value)) return;
e.preventDefault();
var component;
var visibleItems = [];
if (binding.modifiers.message) component = vnode.context;else if (binding.modifiers.contact) component = vnode.child;
if (!dropdown_popover) {
dropdown_popover = document.createElement('div');
dropdown_popover.className = 'lemon-dropdown';
document.body.appendChild(dropdown_popover);
}
dropdown_popover.innerHTML = binding.value.map(function (item) {
var visible;
if (isFunction(item.visible)) {
visible = item.visible(component);
} else {
visible = item.visible === undefined ? true : item.visible;
}
if (visible) {
visibleItems.push(item);
var icon = item.icon ? "<i class=\"lemon-dropdown__icon ".concat(item.icon, "\"></i>") : '';
return "<div style=\"color:".concat(item.color, "\" title=\"").concat(item.text, "\" class=\"lemon-dropdown__item\">").concat(icon, "<span>").concat(item.text, "</span></div>");
}
return '';
}).join("");
dropdown_popover.style.top = "".concat(e.pageY, "px");
dropdown_popover.style.left = "".concat(e.pageX, "px");
dropdown_popover.childNodes.forEach(function (node, index) {
var _visibleItems$index = visibleItems[index],
click = _visibleItems$index.click,
_render = _visibleItems$index.render;
node.addEventListener('click', function (e) {
e.stopPropagation();
if (isFunction(click)) click(e, component, hidePopover);
});
if (isFunction(_render)) {
var ins = external_commonjs_vue_commonjs2_vue_root_Vue_default.a.extend({
render: function render(h) {
return _render(h, component, hidePopover);
}
});
var renderComponent = new ins().$mount();
node.querySelector('span').innerHTML = renderComponent.$el.outerHTML;
}
});
showPopover();
});
},
inserted: function inserted(el, binding, vnode) {}
});
// CONCATENATED MODULE: ./node_modules/cache-loader/dist/cjs.js??ref--12-0!./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./packages/components/messages.vue?vue&type=script&lang=js&
@@ -6784,6 +6874,7 @@ var editor_component = normalizeComponent(
/* harmony default export */ var messagesvue_type_script_lang_js_ = ({
name: "LemonMessages",
components: {},
@@ -6907,17 +6998,18 @@ var editor_component = normalizeComponent(
switch (_context2.prev = _context2.next) {
case 0:
target = e.target;
dropdown.hide();
if (!(target.scrollTop == 0 && this._loading == false && this._loadend == false)) {
_context2.next = 7;
_context2.next = 8;
break;
}
this._loading = true;
_context2.next = 5;
_context2.next = 6;
return this.$nextTick();
case 5:
case 6:
hst = target.scrollHeight;
this.$emit("reach-top",
/*#__PURE__*/
@@ -6950,7 +7042,7 @@ var editor_component = normalizeComponent(
};
}());
case 7:
case 8:
case "end":
return _context2.stop();
}
@@ -7040,6 +7132,7 @@ var messages_component = normalizeComponent(
}
},
props: {
contextmenu: Array,
message: {
type: Object,
default: function _default() {
@@ -7105,6 +7198,13 @@ var messages_component = normalizeComponent(
}, [this.timeFormat(sendTime)])]), h("div", {
"class": "lemon-message__content-flex"
}, [h("div", {
"directives": [{
name: "dropdown",
value: this.IMUI.contextmenu,
modifiers: {
"message": true
}
}],
"class": "lemon-message__content",
"on": {
"click": function click(e) {
@@ -7131,7 +7231,7 @@ var messages_component = normalizeComponent(
color: "#ff2525",
cursor: "pointer"
}
}), this._renderStatue(status)])])])]);
})])])])]);
},
created: function created() {},
mounted: function mounted() {},
@@ -7140,22 +7240,6 @@ var messages_component = normalizeComponent(
methods: {
_emitClick: function _emitClick(e, key) {
this.IMUI.$emit("message-click", e, key, this.message, this.IMUI);
},
_renderStatue: function _renderStatue(status) {// if (status == "going") {
// return <i class="lemon-icon-loading lemonani-spin" />;
// } else if (status == "failed") {
// return (
// <i
// class="lemon-icon-prompt"
// title="重发消息"
// style={{
// color: "#ff2525",
// cursor: "pointer"
// }}
// />
// );
// }
// return;
}
}
});
@@ -7617,6 +7701,7 @@ function componentsvue_type_script_lang_js_objectSpread(target) { for (var i = 1
var allMessages = {};
var emojiMap = {};
@@ -7682,6 +7767,8 @@ var renderDrawerContent = function renderDrawerContent() {};
hideMessageTime: Boolean,
sendKey: Function,
sendText: String,
contextmenu: Array,
contactContextmenu: Array,
user: {
type: Object,
default: function _default() {
@@ -7790,7 +7877,8 @@ var renderDrawerContent = function renderDrawerContent() {};
var scrollToBottom = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
if (allMessages[message.toContactId] === undefined) {
this.updateContact(message.toContactId, {
this.updateContact({
id: message.toContactId,
unread: "+1",
lastSendTime: message.sendTime,
lastContent: this.lastContentRender(message)
@@ -7799,6 +7887,7 @@ var renderDrawerContent = function renderDrawerContent() {};
this._addMessage(message, message.toContactId, 1);
var updateContact = {
id: message.toContactId,
lastContent: this.lastContentRender(message),
lastSendTime: message.sendTime
};
@@ -7811,7 +7900,7 @@ var renderDrawerContent = function renderDrawerContent() {};
updateContact.unread = '+1';
}
this.updateContact(message.toContactId, updateContact);
this.updateContact(updateContact);
}
},
_emitSend: function _emitSend(message, next, file) {
@@ -7836,7 +7925,8 @@ var renderDrawerContent = function renderDrawerContent() {};
this.appendMessage(message, true);
this._emitSend(message, function () {
_this4.updateContact(message.toContactId, {
_this4.updateContact({
id: message.toContactId,
lastContent: _this4.lastContentRender(message),
lastSendTime: message.sendTime
});
@@ -7867,7 +7957,8 @@ var renderDrawerContent = function renderDrawerContent() {};
this.appendMessage(message, true);
this._emitSend(message, function () {
_this5.updateContact(message.toContactId, {
_this5.updateContact({
id: message.toContactId,
lastContent: _this5.lastContentRender(message),
lastSendTime: message.sendTime
});
@@ -8012,7 +8103,14 @@ var renderDrawerContent = function renderDrawerContent() {};
return h("lemon-contact", helper_default()([{
"class": {
"lemon-contact--active": this.currentContactId == props.contact.id
},
"directives": [{
name: "dropdown",
value: this.contactContextmenu,
modifiers: {
"contact": true
}
}]
}, {
"props": props
}, {
@@ -8051,7 +8149,10 @@ var renderDrawerContent = function renderDrawerContent() {};
"directives": [{
name: "show",
value: this.activeSidebar == name
}]
}],
"on": {
"scroll": this._handleSidebarScroll
}
}, [children]);
},
_renderDrawer: function _renderDrawer() {
@@ -8151,12 +8252,22 @@ var renderDrawerContent = function renderDrawerContent() {};
}), h("h4", [curact.displayName]), h("lemon-button", {
"on": {
"click": function click() {
if (isEmpty(curact.lastContent)) {
_this12.updateContact({
id: curact.id,
lastContent: ' '
});
}
_this12.changeContact(curact.id, DEFAULT_MENU_LASTMESSAGES);
}
}
}, ["\u53D1\u9001\u6D88\u606F"])]), curact)]));
return nodes;
},
_handleSidebarScroll: function _handleSidebarScroll() {
dropdown.hide();
},
_addContact: function _addContact(data, t) {
var type = {
0: "unshift",
@@ -8252,16 +8363,25 @@ var renderDrawerContent = function renderDrawerContent() {};
case 6:
this.currentContactId = contactId;
if (this.currentContactId) {
_context2.next = 9;
break;
}
return _context2.abrupt("return", false);
case 9:
this.$emit("change-contact", this.currentContact, this);
if (!isFunction(this.currentContact.renderContainer)) {
_context2.next = 10;
_context2.next = 12;
break;
}
return _context2.abrupt("return");
case 10:
case 12:
if (this.CacheMessageLoaded.has(contactId)) {
this.$refs.messages.loaded();
} else {
@@ -8282,7 +8402,7 @@ var renderDrawerContent = function renderDrawerContent() {};
}, 0);
}
case 12:
case 14:
case "end":
return _context2.stop();
}
@@ -8320,10 +8440,11 @@ var renderDrawerContent = function renderDrawerContent() {};
*/
updateMessage: function updateMessage(message) {
if (!message.id) return false;
delete message.toContactId;
var historyMessage = this.findMessage(message.id);
if (!historyMessage) return false;
historyMessage = Object.assign(historyMessage, message);
historyMessage = Object.assign(historyMessage, message, {
toContactId: historyMessage.toContactId
});
return true;
},
@@ -8495,11 +8616,11 @@ var renderDrawerContent = function renderDrawerContent() {};
/**
* 修改联系人数据
* @param {Contact} data 修改的数据根据 data.id 查找联系人并覆盖传入的值
* @param {Contact} data 修改的数据根据 Contact.id 查找联系人并覆盖传入的值
*/
updateContact: function updateContact(contactId, data) {
updateContact: function updateContact(data) {
var contactId = data.id;
delete data.id;
delete data.toContactId;
var index = this.findContactIndexById(contactId);
if (index !== -1) {
@@ -8543,6 +8664,12 @@ var renderDrawerContent = function renderDrawerContent() {};
if (message) return message;
}
},
findContact: function findContact(contactId) {
return this.getContacts().find(function (_ref4) {
var id = _ref4.id;
return id == contactId;
});
},
/**
* 返回所有联系人
@@ -8558,6 +8685,12 @@ var renderDrawerContent = function renderDrawerContent() {};
getCurrentMessages: function getCurrentMessages() {
return this.currentMessages;
},
setEditorValue: function setEditorValue(val) {
this.$refs.editor.setValue(this.replaceEmojiName(val));
},
getEditorValue: function getEditorValue() {
return this.$refs.editor.getFormatValue();
},
/**
* 返回所有消息
@@ -8608,6 +8741,10 @@ var components_component = normalizeComponent(
// EXTERNAL MODULE: ./packages/styles/common/index.styl
var common = __webpack_require__("6a2b");
// CONCATENATED MODULE: ./packages/directives/index.js
external_commonjs_vue_commonjs2_vue_root_Vue_default.a.directive('dropdown', dropdown);
// CONCATENATED MODULE: ./packages/index.js
@@ -8626,7 +8763,8 @@ var common = __webpack_require__("6a2b");
var version = "0.1";
var version = "1.4.2";
var packages_components = [components, components_contact, messages, editor, avatar, badge, components_button, popover, tabs, basic, message_text, message_image, file, message_event];
var install = function install(Vue) {
+1 -1
View File
File diff suppressed because one or more lines are too long
+198 -60
View File
@@ -1,13 +1,13 @@
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
module.exports = factory(require("vue"));
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["index"] = factory();
exports["index"] = factory(require("vue"));
else
root["index"] = factory();
})((typeof self !== 'undefined' ? self : this), function() {
root["index"] = factory(root["Vue"]);
})((typeof self !== 'undefined' ? self : this), function(__WEBPACK_EXTERNAL_MODULE__8bbf__) {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
@@ -3196,6 +3196,13 @@ module.exports = {
};
/***/ }),
/***/ "8bbf":
/***/ (function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE__8bbf__;
/***/ }),
/***/ "8e60":
@@ -5575,7 +5582,7 @@ var tabs_render, staticRenderFns
/* normalize component */
var component = normalizeComponent(
var tabs_component = normalizeComponent(
components_tabsvue_type_script_lang_js_,
tabs_render,
staticRenderFns,
@@ -5586,7 +5593,7 @@ var component = normalizeComponent(
)
/* harmony default export */ var tabs = (component.exports);
/* harmony default export */ var tabs = (tabs_component.exports);
// EXTERNAL MODULE: ./node_modules/regenerator-runtime/runtime.js
var runtime = __webpack_require__("96cf");
@@ -5721,7 +5728,7 @@ var triggerEvents = {
"style": "position:relative"
}, [h("transition", {
"attrs": {
"name": "slide-top"
"name": "lemon-slide-top"
}
}, [this.visible && h("div", {
"class": "lemon-popover",
@@ -6193,6 +6200,10 @@ function arrayIntersect(a, b) {
function clearHtml(str) {
return str.replace(/<.*?>/ig, "");
} //清除字符串内的所有HTML标签,除了IMG
function clearHtmlExcludeImg(str) {
return str.replace(/<(?!img).*?>/ig, "");
}
function error(text) {
throw new Error(text);
@@ -6258,6 +6269,14 @@ function generateUUID() {
/* harmony default export */ var contactvue_type_script_lang_js_ = ({
name: "LemonContact",
components: {},
inject: {
IMUI: {
from: 'IMUI',
default: function _default() {
return this;
}
}
},
data: function data() {
return {};
},
@@ -6292,24 +6311,16 @@ function generateUUID() {
watch: {},
methods: {
_renderInner: function _renderInner() {
var _this2 = this;
var h = this.$createElement;
var contact = this.contact;
return [h("lemon-badge", {
"attrs": {
"count": !this.simple ? contact.unread : 0,
"native-on-click": function nativeOnClick(e) {
return _this2._handleBubbleClick(e, contact);
}
"count": !this.simple ? contact.unread : 0
},
"class": "lemon-contact__avatar"
}, [h("lemon-avatar", {
"attrs": {
"size": 40,
"native-on-click": function nativeOnClick(e) {
return _this2._handleAvatarClick(e, contact);
},
"src": contact.avatar
}
})]), h("div", {
@@ -6330,14 +6341,6 @@ function generateUUID() {
},
_handleClick: function _handleClick(e, data) {
this.$emit("click", data);
},
_handleAvatarClick: function _handleAvatarClick(e, data) {
e.stopPropagation();
this.$emit("avatar-click", data);
},
_handleBubbleClick: function _handleBubbleClick(e, data) {
e.stopPropagation();
this.$emit("bubble-click", data);
}
}
});
@@ -6671,6 +6674,8 @@ var isInitTool = false;
exec("<img emoji-name=\"".concat(item.name, "\" src=\"").concat(item.src, "\"></img>"));
this._checkSubmitDisabled();
this._saveLastRange();
},
selectFile: function () {
@@ -6733,7 +6738,7 @@ var isInitTool = false;
return toEmojiName(this.$refs.textarea.innerHTML);
},
_checkSubmitDisabled: function _checkSubmitDisabled() {
this.submitDisabled = !this.$refs.textarea.innerText.trim();
this.submitDisabled = !clearHtmlExcludeImg(this.$refs.textarea.innerHTML.trim());
},
_handleSend: function _handleSend(e) {
var text = this.getFormatValue();
@@ -6757,6 +6762,11 @@ var isInitTool = false;
initEmoji: function initEmoji(data) {
emojiData = data;
this.$forceUpdate();
},
setValue: function setValue(val) {
this.$refs.textarea.innerHTML = val;
this._checkSubmitDisabled();
}
}
});
@@ -6786,6 +6796,86 @@ var editor_component = normalizeComponent(
)
/* harmony default export */ var editor = (editor_component.exports);
// EXTERNAL MODULE: external {"commonjs":"vue","commonjs2":"vue","root":"Vue"}
var external_commonjs_vue_commonjs2_vue_root_Vue_ = __webpack_require__("8bbf");
var external_commonjs_vue_commonjs2_vue_root_Vue_default = /*#__PURE__*/__webpack_require__.n(external_commonjs_vue_commonjs2_vue_root_Vue_);
// CONCATENATED MODULE: ./packages/directives/dropdown.js
var dropdown_popover;
var hidePopover = function hidePopover() {
if (dropdown_popover) dropdown_popover.style.display = 'none';
};
var showPopover = function showPopover() {
if (dropdown_popover) dropdown_popover.style.display = 'block';
};
document.addEventListener('click', function (e) {
hidePopover();
});
/* harmony default export */ var dropdown = ({
hide: hidePopover,
bind: function bind(el, binding, vnode) {
el.addEventListener('contextmenu', function (e) {
if (isEmpty(binding.value) || !Array.isArray(binding.value)) return;
e.preventDefault();
var component;
var visibleItems = [];
if (binding.modifiers.message) component = vnode.context;else if (binding.modifiers.contact) component = vnode.child;
if (!dropdown_popover) {
dropdown_popover = document.createElement('div');
dropdown_popover.className = 'lemon-dropdown';
document.body.appendChild(dropdown_popover);
}
dropdown_popover.innerHTML = binding.value.map(function (item) {
var visible;
if (isFunction(item.visible)) {
visible = item.visible(component);
} else {
visible = item.visible === undefined ? true : item.visible;
}
if (visible) {
visibleItems.push(item);
var icon = item.icon ? "<i class=\"lemon-dropdown__icon ".concat(item.icon, "\"></i>") : '';
return "<div style=\"color:".concat(item.color, "\" title=\"").concat(item.text, "\" class=\"lemon-dropdown__item\">").concat(icon, "<span>").concat(item.text, "</span></div>");
}
return '';
}).join("");
dropdown_popover.style.top = "".concat(e.pageY, "px");
dropdown_popover.style.left = "".concat(e.pageX, "px");
dropdown_popover.childNodes.forEach(function (node, index) {
var _visibleItems$index = visibleItems[index],
click = _visibleItems$index.click,
_render = _visibleItems$index.render;
node.addEventListener('click', function (e) {
e.stopPropagation();
if (isFunction(click)) click(e, component, hidePopover);
});
if (isFunction(_render)) {
var ins = external_commonjs_vue_commonjs2_vue_root_Vue_default.a.extend({
render: function render(h) {
return _render(h, component, hidePopover);
}
});
var renderComponent = new ins().$mount();
node.querySelector('span').innerHTML = renderComponent.$el.outerHTML;
}
});
showPopover();
});
},
inserted: function inserted(el, binding, vnode) {}
});
// CONCATENATED MODULE: ./node_modules/cache-loader/dist/cjs.js??ref--12-0!./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./packages/components/messages.vue?vue&type=script&lang=js&
@@ -6793,6 +6883,7 @@ var editor_component = normalizeComponent(
/* harmony default export */ var messagesvue_type_script_lang_js_ = ({
name: "LemonMessages",
components: {},
@@ -6916,17 +7007,18 @@ var editor_component = normalizeComponent(
switch (_context2.prev = _context2.next) {
case 0:
target = e.target;
dropdown.hide();
if (!(target.scrollTop == 0 && this._loading == false && this._loadend == false)) {
_context2.next = 7;
_context2.next = 8;
break;
}
this._loading = true;
_context2.next = 5;
_context2.next = 6;
return this.$nextTick();
case 5:
case 6:
hst = target.scrollHeight;
this.$emit("reach-top",
/*#__PURE__*/
@@ -6959,7 +7051,7 @@ var editor_component = normalizeComponent(
};
}());
case 7:
case 8:
case "end":
return _context2.stop();
}
@@ -7049,6 +7141,7 @@ var messages_component = normalizeComponent(
}
},
props: {
contextmenu: Array,
message: {
type: Object,
default: function _default() {
@@ -7114,6 +7207,13 @@ var messages_component = normalizeComponent(
}, [this.timeFormat(sendTime)])]), h("div", {
"class": "lemon-message__content-flex"
}, [h("div", {
"directives": [{
name: "dropdown",
value: this.IMUI.contextmenu,
modifiers: {
"message": true
}
}],
"class": "lemon-message__content",
"on": {
"click": function click(e) {
@@ -7140,7 +7240,7 @@ var messages_component = normalizeComponent(
color: "#ff2525",
cursor: "pointer"
}
}), this._renderStatue(status)])])])]);
})])])])]);
},
created: function created() {},
mounted: function mounted() {},
@@ -7149,22 +7249,6 @@ var messages_component = normalizeComponent(
methods: {
_emitClick: function _emitClick(e, key) {
this.IMUI.$emit("message-click", e, key, this.message, this.IMUI);
},
_renderStatue: function _renderStatue(status) {// if (status == "going") {
// return <i class="lemon-icon-loading lemonani-spin" />;
// } else if (status == "failed") {
// return (
// <i
// class="lemon-icon-prompt"
// title="重发消息"
// style={{
// color: "#ff2525",
// cursor: "pointer"
// }}
// />
// );
// }
// return;
}
}
});
@@ -7626,6 +7710,7 @@ function componentsvue_type_script_lang_js_objectSpread(target) { for (var i = 1
var allMessages = {};
var emojiMap = {};
@@ -7691,6 +7776,8 @@ var renderDrawerContent = function renderDrawerContent() {};
hideMessageTime: Boolean,
sendKey: Function,
sendText: String,
contextmenu: Array,
contactContextmenu: Array,
user: {
type: Object,
default: function _default() {
@@ -7799,7 +7886,8 @@ var renderDrawerContent = function renderDrawerContent() {};
var scrollToBottom = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
if (allMessages[message.toContactId] === undefined) {
this.updateContact(message.toContactId, {
this.updateContact({
id: message.toContactId,
unread: "+1",
lastSendTime: message.sendTime,
lastContent: this.lastContentRender(message)
@@ -7808,6 +7896,7 @@ var renderDrawerContent = function renderDrawerContent() {};
this._addMessage(message, message.toContactId, 1);
var updateContact = {
id: message.toContactId,
lastContent: this.lastContentRender(message),
lastSendTime: message.sendTime
};
@@ -7820,7 +7909,7 @@ var renderDrawerContent = function renderDrawerContent() {};
updateContact.unread = '+1';
}
this.updateContact(message.toContactId, updateContact);
this.updateContact(updateContact);
}
},
_emitSend: function _emitSend(message, next, file) {
@@ -7845,7 +7934,8 @@ var renderDrawerContent = function renderDrawerContent() {};
this.appendMessage(message, true);
this._emitSend(message, function () {
_this4.updateContact(message.toContactId, {
_this4.updateContact({
id: message.toContactId,
lastContent: _this4.lastContentRender(message),
lastSendTime: message.sendTime
});
@@ -7876,7 +7966,8 @@ var renderDrawerContent = function renderDrawerContent() {};
this.appendMessage(message, true);
this._emitSend(message, function () {
_this5.updateContact(message.toContactId, {
_this5.updateContact({
id: message.toContactId,
lastContent: _this5.lastContentRender(message),
lastSendTime: message.sendTime
});
@@ -8021,7 +8112,14 @@ var renderDrawerContent = function renderDrawerContent() {};
return h("lemon-contact", helper_default()([{
"class": {
"lemon-contact--active": this.currentContactId == props.contact.id
},
"directives": [{
name: "dropdown",
value: this.contactContextmenu,
modifiers: {
"contact": true
}
}]
}, {
"props": props
}, {
@@ -8060,7 +8158,10 @@ var renderDrawerContent = function renderDrawerContent() {};
"directives": [{
name: "show",
value: this.activeSidebar == name
}]
}],
"on": {
"scroll": this._handleSidebarScroll
}
}, [children]);
},
_renderDrawer: function _renderDrawer() {
@@ -8160,12 +8261,22 @@ var renderDrawerContent = function renderDrawerContent() {};
}), h("h4", [curact.displayName]), h("lemon-button", {
"on": {
"click": function click() {
if (isEmpty(curact.lastContent)) {
_this12.updateContact({
id: curact.id,
lastContent: ' '
});
}
_this12.changeContact(curact.id, DEFAULT_MENU_LASTMESSAGES);
}
}
}, ["\u53D1\u9001\u6D88\u606F"])]), curact)]));
return nodes;
},
_handleSidebarScroll: function _handleSidebarScroll() {
dropdown.hide();
},
_addContact: function _addContact(data, t) {
var type = {
0: "unshift",
@@ -8261,16 +8372,25 @@ var renderDrawerContent = function renderDrawerContent() {};
case 6:
this.currentContactId = contactId;
if (this.currentContactId) {
_context2.next = 9;
break;
}
return _context2.abrupt("return", false);
case 9:
this.$emit("change-contact", this.currentContact, this);
if (!isFunction(this.currentContact.renderContainer)) {
_context2.next = 10;
_context2.next = 12;
break;
}
return _context2.abrupt("return");
case 10:
case 12:
if (this.CacheMessageLoaded.has(contactId)) {
this.$refs.messages.loaded();
} else {
@@ -8291,7 +8411,7 @@ var renderDrawerContent = function renderDrawerContent() {};
}, 0);
}
case 12:
case 14:
case "end":
return _context2.stop();
}
@@ -8329,10 +8449,11 @@ var renderDrawerContent = function renderDrawerContent() {};
*/
updateMessage: function updateMessage(message) {
if (!message.id) return false;
delete message.toContactId;
var historyMessage = this.findMessage(message.id);
if (!historyMessage) return false;
historyMessage = Object.assign(historyMessage, message);
historyMessage = Object.assign(historyMessage, message, {
toContactId: historyMessage.toContactId
});
return true;
},
@@ -8504,11 +8625,11 @@ var renderDrawerContent = function renderDrawerContent() {};
/**
* 修改联系人数据
* @param {Contact} data 修改的数据根据 data.id 查找联系人并覆盖传入的值
* @param {Contact} data 修改的数据根据 Contact.id 查找联系人并覆盖传入的值
*/
updateContact: function updateContact(contactId, data) {
updateContact: function updateContact(data) {
var contactId = data.id;
delete data.id;
delete data.toContactId;
var index = this.findContactIndexById(contactId);
if (index !== -1) {
@@ -8552,6 +8673,12 @@ var renderDrawerContent = function renderDrawerContent() {};
if (message) return message;
}
},
findContact: function findContact(contactId) {
return this.getContacts().find(function (_ref4) {
var id = _ref4.id;
return id == contactId;
});
},
/**
* 返回所有联系人
@@ -8567,6 +8694,12 @@ var renderDrawerContent = function renderDrawerContent() {};
getCurrentMessages: function getCurrentMessages() {
return this.currentMessages;
},
setEditorValue: function setEditorValue(val) {
this.$refs.editor.setValue(this.replaceEmojiName(val));
},
getEditorValue: function getEditorValue() {
return this.$refs.editor.getFormatValue();
},
/**
* 返回所有消息
@@ -8617,6 +8750,10 @@ var components_component = normalizeComponent(
// EXTERNAL MODULE: ./packages/styles/common/index.styl
var common = __webpack_require__("6a2b");
// CONCATENATED MODULE: ./packages/directives/index.js
external_commonjs_vue_commonjs2_vue_root_Vue_default.a.directive('dropdown', dropdown);
// CONCATENATED MODULE: ./packages/index.js
@@ -8635,7 +8772,8 @@ var common = __webpack_require__("6a2b");
var version = "0.1";
var version = "1.4.2";
var packages_components = [components, components_contact, messages, editor, avatar, badge, components_button, popover, tabs, basic, message_text, message_image, file, message_event];
var install = function install(Vue) {
+1 -1
View File
File diff suppressed because one or more lines are too long
+236 -5
View File
@@ -18,6 +18,8 @@
<lemon-imui
:user="user"
ref="IMUI"
:contextmenu="contextmenu"
:contact-contextmenu="contactContextmenu"
:theme="theme"
:hide-menu="hideMenu"
:hide-menu-avatar="hideMenuAvatar"
@@ -30,6 +32,12 @@
@menu-avatar-click="handleMenuAvatarClick"
@send="handleSend"
>
<template #cover>
<div class="cover">
<i class="lemon-icon-message"></i>
<p><b>自定义封面 Lemon</b> IMUI</p>
</div>
</template>
<template #message-title="contact">
<span>{{ contact.displayName }}</span>
<small class="more" @click="changeDrawer(contact,$refs.IMUI)">{{($refs.IMUI ? $refs.IMUI.drawerVisible : false) ? '关闭' : '打开'}}抽屉</small>
@@ -266,6 +274,58 @@
</tr>
</table>
<div class="title">右键菜单 ContextmenuItem</div>
<table class="table">
<tr class="table-head">
<th>名称</th>
<th>说明</th>
<th>类型</th>
<th>示例</th>
</tr>
<tr>
<td width="150">text</td>
<td width="350">显示文字</td>
<td width="150">String</td>
<td width="100">-</td>
<td></td>
</tr>
<tr>
<td width="150">color</td>
<td width="350">颜色</td>
<td width="150">String</td>
<td width="100">-</td>
<td></td>
</tr>
<tr>
<td width="150">icon</td>
<td width="350">图标 class</td>
<td width="150">String</td>
<td width="100">-</td>
<td></td>
</tr>
<tr>
<td width="150">click</td>
<td width="350">点击事件调用hide方法隐藏右键菜单</td>
<td width="150">Function(e,instance,hide)</td>
<td width="100">-</td>
<td></td>
</tr>
<tr>
<td width="150">visible</td>
<td width="350">是否显示的判断函数</td>
<td width="150">Function(instance)</td>
<td width="100">-</td>
<td></td>
</tr>
<tr>
<td width="150">render</td>
<td width="350">负责样式的渲染函数使用render的时候text属性会失去作用调用hide方法隐藏右键菜单</td>
<td width="150">Function(e,instance,hide)</td>
<td width="100">-</td>
<td></td>
</tr>
</table>
<div class="title">组件属性</div>
<table class="table">
<tr class="table-head">
@@ -374,6 +434,20 @@
<td>false</td>
<td></td>
</tr>
<tr>
<td>contextmenu</td>
<td>聊天消息右键菜单配置</td>
<td>[ContextmenuItem]</td>
<td>-</td>
<td></td>
</tr>
<tr>
<td>contactContextmenu</td>
<td>联系人右键菜单配置</td>
<td>[ContextmenuItem]</td>
<td>-</td>
<td></td>
</tr>
</table>
<div class="title">组件方法</div>
@@ -592,6 +666,21 @@
<td>-</td>
<td></td>
</tr>
<tr>
<td>setEditorValue</td>
<td>设置编辑框内容</td>
<td>Function(string)</td>
<td>-</td>
<td></td>
</tr>
<tr>
<td>getEditorValue</td>
<td>获取编辑框内容</td>
<td>Function()=>string</td>
<td>-</td>
<td></td>
</tr>
</table>
<div class="title">组件插槽</div>
@@ -820,6 +909,7 @@ import LemonMessageVoice from './lemon-message-voice';
import packageData from '../package.json';
Vue.component(LemonMessageVoice.name,LemonMessageVoice);
const tip = `export default {
//组件的name必须以lemonMessage开头,后面跟上 Message.type
name: "lemonMessageVoice",
@@ -891,6 +981,102 @@ export default {
data() {
return {
theme:'default',
contactContextmenu:[{
text:'删除该聊天',
click:(e,instance,hide)=>{
const {IMUI,contact} = instance;
IMUI.updateContact({
id:contact.id,
lastContent:null,
});
if(IMUI.currentContactId == contact.id) IMUI.changeContact(null);
hide();
},
},{
text:'设置备注和标签',
},{
text:'投诉',
},{
icon:'lemon-icon-message',
render:(h,instance,hide)=>{
return <div style="display:flex;justify-content:space-between;align-items:center;width:130px">
<span>加入黑名单</span>
<span>
<input type="checkbox" id="switch" />
<label id="switch-label" for="switch">Toggle</label>
</span>
</div>;
},
},{
click(e,instance,hide){
const {IMUI,contact} = instance;
IMUI.removeContact(contact.id);
if(IMUI.currentContactId == contact.id) IMUI.changeContact(null);
hide();
},
color:'red',
text:'删除好友',
}],
contextmenu:[{
click:(e,instance,hide)=>{
const { IMUI,message } = instance;
const data = {
id:generateRandId(),
type:'event',
//使用 jsx 时 click必须使用箭头函数(使上下文停留在vue内)
content:<span>你撤回了一条消息 <span v-show={message.type == 'text'} style="color:#333;cursor:pointer" content={message.content} on-click={(e)=>{
IMUI.setEditorValue(e.target.getAttribute('content'));
}}>重新编辑</span></span>,
toContactId:message.toContactId,
sendTime:getTime(),
};
IMUI.removeMessage(message.id);
IMUI.appendMessage(data,true);
hide();
},
visible:(instance)=>{
return instance.message.fromUser.id == this.user.id;
},
text:'撤回消息',
},
{
visible:(instance)=>{
return instance.message.fromUser.id != this.user.id;
},
text:'举报',
},
{
text:'转发',
},
{
visible:(instance)=>{
return instance.message.type == 'text';
},
text:'复制文字',
},
{
visible:(instance)=>{
return instance.message.type == 'image';
},
text:'下载图片',
},
{
visible:(instance)=>{
return instance.message.type == 'file';
},
text:'下载文件',
},
{
click:(e,instance,hide)=>{
const { IMUI,message } = instance;
IMUI.removeMessage(message.id);
hide();
},
icon:'lemon-icon-folder',
color:'red',
text:'删除',
}],
tip:tip,
packageData,
hideMenuAvatar: false,
@@ -950,7 +1136,6 @@ export default {
};
const { IMUI } = this.$refs;
setTimeout(()=>{
console.log(IMUI.hasContact('cont1act-3'));
},2000);
@@ -962,7 +1147,7 @@ export default {
let contactList = [
{ ...contactData1 },
{ ...contactData2 },
{ ...contactData3 }
{ ...contactData3 },
//...Array(100).fill(contactData1)
];
@@ -1479,14 +1664,15 @@ export default {
const message = {
id:generateRandId(),
type:'event',
content:<span>邀请你加入群聊 <b style="color:#333;cursor:pointer" on-click={()=>alert('OK')}>接受</b></span>,
content:<span>邀请你加入群聊 <span style="color:#333;cursor:pointer" on-click={()=>alert('OK')}>接受</span></span>,
toContactId:'contact-3',
sendTime:getTime(),
};
IMUI.appendMessage(message,true);
},
updateContact() {
this.$refs.IMUI.updateContact("contact-3", {
this.$refs.IMUI.updateContact({
id:"contact-3",
unread: 10,
displayName: generateRandWord(),
lastSendTime: getTime(),
@@ -1507,7 +1693,8 @@ export default {
},
handleChangeContact(contact,instance) {
console.log("Event:change-contact");
instance.updateContact(contact.id, {
instance.updateContact({
id:contact.id,
//displayName: "123",
unread: 0
});
@@ -1710,4 +1897,48 @@ pre
.lemon-simple .lemon-drawer{
z-index:4
}
input#switch[type=checkbox]{
height: 0;
width: 0;
display:none;
}
label#switch-label {
cursor: pointer;
text-indent: -9999px;
width: 34px;
height: 20px;
background: #aaa;
display: block;
border-radius: 100px;
position: relative;
}
label#switch-label:after {
content: '';
position: absolute;
top: 2px;
left: 2px;
width: 16px;
height: 16px;
background: #fff;
border-radius: 20px;
transition: 0.3s;
}
input#switch:checked + label {
background: #0fd547;
}
input#switch:checked + label:after {
left: calc(100% - 2px);
transform: translateX(-100%);
}
label#switch-label:active:after {
width: 20px;
}
</style>
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><link rel=icon href=favicon.ico><title>Lemon IMUI</title><link href=css/index.8db04478.css rel=preload as=style><link href=js/chunk-vendors.e4810482.js rel=preload as=script><link href=js/index.dfad42c7.js rel=preload as=script><link href=css/index.8db04478.css rel=stylesheet></head><body><noscript><strong>We're sorry but flat-im doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script src=js/chunk-vendors.e4810482.js></script><script src=js/index.dfad42c7.js></script></body></html>
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><link rel=icon href=favicon.ico><title>Lemon IMUI</title><link href=css/index.fed1a091.css rel=preload as=style><link href=js/chunk-vendors.e4810482.js rel=preload as=script><link href=js/index.4318ecd4.js rel=preload as=script><link href=css/index.fed1a091.css rel=stylesheet></head><body><noscript><strong>We're sorry but flat-im doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script src=js/chunk-vendors.e4810482.js></script><script src=js/index.4318ecd4.js></script></body></html>
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "lemon-imui",
"version": "1.4.2",
"version": "1.5.0",
"main": "dist/index.umd.min.js",
"description": "基于 VUE2.0 的 IM 聊天组件",
"homepage": "https://github.com/fanjyy/lemon-imui",
+8 -10
View File
@@ -4,6 +4,14 @@ import { timeFormat,useScopedSlot } from "utils";
export default {
name: "LemonContact",
components: {},
inject: {
IMUI: {
from:'IMUI',
default (){
return this;
}
}
},
data() {
return {};
},
@@ -39,11 +47,9 @@ export default {
<lemon-badge
count={!this.simple ? contact.unread : 0}
class="lemon-contact__avatar"
native-on-click={e => this._handleBubbleClick(e, contact)}
>
<lemon-avatar
size={40}
native-on-click={e => this._handleAvatarClick(e, contact)}
src={contact.avatar}
/>
</lemon-badge>,
@@ -71,14 +77,6 @@ export default {
_handleClick(e, data) {
this.$emit("click", data);
},
_handleAvatarClick(e, data) {
e.stopPropagation();
this.$emit("avatar-click", data);
},
_handleBubbleClick(e, data) {
e.stopPropagation();
this.$emit("bubble-click", data);
}
}
};
</script>
+8 -3
View File
@@ -1,5 +1,5 @@
<script>
import { toEmojiName,useScopedSlot,clearHtml } from "utils";
import { toEmojiName,useScopedSlot,clearHtmlExcludeImg } from "utils";
const exec = (val, command = "insertHTML") => {
document.execCommand(command, false, val);
};
@@ -212,6 +212,7 @@ export default {
_handleSelectEmoji(item) {
this._focusLastRange();
exec(`<img emoji-name="${item.name}" src="${item.src}"></img>`);
this._checkSubmitDisabled();
this._saveLastRange();
},
async selectFile(accept) {
@@ -248,7 +249,7 @@ export default {
return toEmojiName(this.$refs.textarea.innerHTML);
},
_checkSubmitDisabled() {
this.submitDisabled = !this.$refs.textarea.innerText.trim();
this.submitDisabled = !clearHtmlExcludeImg(this.$refs.textarea.innerHTML.trim());
},
_handleSend(e) {
const text = this.getFormatValue();
@@ -269,7 +270,11 @@ export default {
initEmoji(data) {
emojiData = data;
this.$forceUpdate();
}
},
setValue(val){
this.$refs.textarea.innerHTML = val;
this._checkSubmitDisabled();
},
}
};
</script>
+75 -10
View File
@@ -1,6 +1,7 @@
<script>
import { useScopedSlot, funCall, generateUUID,cloneDeep } from "utils";
import { isFunction, isString, isEmpty } from "utils/validate";
import dropdown from "../directives/dropdown";
import {
DEFAULT_MENUS,
DEFAULT_MENU_LASTMESSAGES,
@@ -68,6 +69,8 @@ export default {
hideMessageTime:Boolean,
sendKey:Function,
sendText:String,
contextmenu:Array,
contactContextmenu:Array,
user: {
type: Object,
default: () => {
@@ -153,7 +156,8 @@ export default {
*/
appendMessage(message,scrollToBottom = false) {
if(allMessages[message.toContactId] === undefined){
this.updateContact(message.toContactId, {
this.updateContact({
id:message.toContactId,
unread: "+1",
lastSendTime: message.sendTime,
lastContent: this.lastContentRender(message)
@@ -161,6 +165,7 @@ export default {
}else{
this._addMessage(message,message.toContactId, 1);
const updateContact = {
id:message.toContactId,
lastContent: this.lastContentRender(message),
lastSendTime: message.sendTime
}
@@ -171,7 +176,7 @@ export default {
}else{
updateContact.unread = '+1';
}
this.updateContact(message.toContactId,updateContact);
this.updateContact(updateContact);
}
},
_emitSend(message, next, file) {
@@ -189,7 +194,8 @@ export default {
const message = this._createMessage({ content: text });
this.appendMessage(message,true);
this._emitSend(message, () => {
this.updateContact(message.toContactId, {
this.updateContact({
id:message.toContactId,
lastContent: this.lastContentRender(message),
lastSendTime: message.sendTime
});
@@ -216,7 +222,8 @@ export default {
this._emitSend(
message,
() => {
this.updateContact(message.toContactId, {
this.updateContact({
id:message.toContactId,
lastContent: this.lastContentRender(message),
lastSendTime: message.sendTime
});
@@ -356,6 +363,7 @@ export default {
class={{
"lemon-contact--active": this.currentContactId == props.contact.id
}}
v-dropdown_contact={this.contactContextmenu}
props={props}
on-click={click}
scopedSlots={{default:slot}}
@@ -394,7 +402,7 @@ export default {
},
_renderSidebar(children, name) {
return (
<div class="lemon-sidebar" v-show={this.activeSidebar == name}>
<div class="lemon-sidebar" v-show={this.activeSidebar == name} on-scroll={this._handleSidebarScroll}>
{children}
</div>
);
@@ -487,6 +495,12 @@ export default {
<h4>{curact.displayName}</h4>
<lemon-button
on-click={() => {
if(isEmpty(curact.lastContent)){
this.updateContact({
id:curact.id,
lastContent:' ',
});
}
this.changeContact(curact.id, DEFAULT_MENU_LASTMESSAGES);
}}
>
@@ -499,6 +513,9 @@ export default {
);
return nodes;
},
_handleSidebarScroll(){
dropdown.hide();
},
_addContact(data, t) {
const type = {
0: "unshift",
@@ -566,6 +583,7 @@ export default {
}
this.currentContactId = contactId;
if(!this.currentContactId) return false;
this.$emit("change-contact", this.currentContact,this);
if (isFunction(this.currentContact.renderContainer)) {
return;
@@ -606,12 +624,14 @@ export default {
*/
updateMessage(message) {
if(!message.id) return false;
delete message.toContactId;
let historyMessage = this.findMessage(message.id);
if(!historyMessage) return false;
historyMessage = Object.assign(
historyMessage,
message
message,
{
toContactId:historyMessage.toContactId
}
);
return true;
},
@@ -769,11 +789,11 @@ export default {
},
/**
* 修改联系人数据
* @param {Contact} data 修改的数据根据 data.id 查找联系人并覆盖传入的值
* @param {Contact} data 修改的数据根据 Contact.id 查找联系人并覆盖传入的值
*/
updateContact(contactId, data) {
updateContact(data) {
const contactId = data.id;
delete data.id;
delete data.toContactId;
const index = this.findContactIndexById(contactId);
if (index !== -1) {
@@ -812,6 +832,9 @@ export default {
if(message) return message;
}
},
findContact(contactId){
return this.getContacts().find(({id})=>id == contactId);
},
/**
* 返回所有联系人
* @return {Array<Contact>}
@@ -826,6 +849,12 @@ export default {
getCurrentMessages() {
return this.currentMessages;
},
setEditorValue(val){
this.$refs.editor.setValue(this.replaceEmojiName(val));
},
getEditorValue(){
return this.$refs.editor.getFormatValue();
},
/**
* 返回所有消息
* @return {Object<Contact.id,Message>}
@@ -985,4 +1014,40 @@ bezier = cubic-bezier(0.645, 0.045, 0.355, 1)
.lemon-menu
.lemon-sidebar
display none
+b(lemon-dropdown)
border-radius 4px
font-size 14px
font-variant tabular-nums
line-height 1.5
color rgba(0, 0, 0, 0.65)
z-index 10
background-color #fff
border-radius 4px
box-shadow 0 2px 8px rgba(0, 0, 0, 0.06)
position absolute
transform-origin 50% 150%
box-sizing border-box
user-select none
overflow hidden
+e(item)
font-size 12px
line-height 14px
padding 8px 10px
cursor pointer
display flex
align-items center
color #444
> span
display inline-block
flex none
//max-width 100px
ellipsis()
&:hover
background #f3f3f3
color #000
&:active
background #e9e9e9
+e(icon)
font-size 16px
margin-right 4px
</style>
+2 -18
View File
@@ -11,6 +11,7 @@ export default {
}
},
props: {
contextmenu:Array,
message: {
type: Object,
default: () => {
@@ -66,6 +67,7 @@ export default {
</div>
<div class="lemon-message__content-flex">
<div
v-dropdown_message={this.IMUI.contextmenu}
class="lemon-message__content"
on-click={e => {
this._emitClick(e, "content");
@@ -93,7 +95,6 @@ export default {
cursor: "pointer"
}}
/>
{this._renderStatue(status)}
</div>
</div>
</div>
@@ -108,23 +109,6 @@ export default {
_emitClick(e, key) {
this.IMUI.$emit("message-click", e, key, this.message,this.IMUI);
},
_renderStatue(status) {
// if (status == "going") {
// return <i class="lemon-icon-loading lemonani-spin" />;
// } else if (status == "failed") {
// return (
// <i
// class="lemon-icon-prompt"
// title=""
// style={{
// color: "#ff2525",
// cursor: "pointer"
// }}
// />
// );
// }
// return;
},
}
};
</script>
+2
View File
@@ -1,5 +1,6 @@
<script>
import { hoursTimeFormat } from "utils";
import dropdown from "../directives/dropdown";
export default {
name: "LemonMessages",
components: {},
@@ -110,6 +111,7 @@ export default {
},
async _handleScroll(e) {
const { target } = e;
dropdown.hide();
if (
target.scrollTop == 0 &&
this._loading == false &&
+5 -5
View File
@@ -51,7 +51,7 @@ export default {
render() {
return (
<span style="position:relative">
<transition name="slide-top">
<transition name="lemon-slide-top">
{this.visible && (
<div
class="lemon-popover"
@@ -117,7 +117,7 @@ export default {
z-index 10
background-color #fff
border-radius 4px
box-shadow 0 2px 8px rgba(0, 0, 0, 0.15)
box-shadow 0 2px 8px rgba(0, 0, 0, 0.08)
position absolute
transform-origin 50% 150%
+e(content)
@@ -135,9 +135,9 @@ export default {
width 8px
height 8px
background #fff
.slide-top-leave-active ,.slide-top-enter-active
transition all .3s cubic-bezier(0.645, 0.045, 0.355, 1)
.slide-top-enter, .slide-top-leave-to
.lemon-slide-top-leave-active ,.lemon-slide-top-enter-active
transition all .2s cubic-bezier(0.645, 0.045, 0.355, 1)
.lemon-slide-top-enter, .lemon-slide-top-leave-to
transform translateY(-10px) scale(.8)
opacity 0
</style>
+70
View File
@@ -0,0 +1,70 @@
import Vue from 'vue';
import {isFunction,isEmpty} from 'utils/validate';
let popover;
const hidePopover = ()=>{
if(popover) popover.style.display = 'none'
}
const showPopover = ()=>{
if(popover) popover.style.display = 'block'
}
document.addEventListener('click',(e)=>{
hidePopover()
});
export default{
hide:hidePopover,
bind(el, binding, vnode){
el.addEventListener('contextmenu',(e)=>{
if(isEmpty(binding.value) || !Array.isArray(binding.value)) return;
e.preventDefault();
let component;
let visibleItems = []
if(binding.modifiers.message) component = vnode.context;
else if(binding.modifiers.contact) component = vnode.child;
if(!popover){
popover = document.createElement('div');
popover.className = 'lemon-dropdown';
document.body.appendChild(popover);
}
popover.innerHTML = binding.value.map((item)=>{
let visible;
if(isFunction(item.visible)){
visible = item.visible(component);
}else{
visible = item.visible === undefined ? true : item.visible;
}
if(visible){
visibleItems.push(item);
const icon = item.icon ? `<i class="lemon-dropdown__icon ${item.icon}"></i>` : '';
return `<div style="color:${item.color}" title="${item.text}" class="lemon-dropdown__item">${icon}<span>${item.text}</span></div>`;
}
return '';
}).join("");
popover.style.top = `${e.pageY}px`;
popover.style.left = `${e.pageX}px`;
popover.childNodes.forEach((node,index)=>{
const {click,render} = visibleItems[index];
node.addEventListener('click',(e)=>{
e.stopPropagation();
if(isFunction(click)) click(e,component,hidePopover);
});
if(isFunction(render)){
const ins = Vue.extend({render:(h)=>{
return render(h,component,hidePopover);
}});
const renderComponent = new ins().$mount();
node.querySelector('span').innerHTML = renderComponent.$el.outerHTML;
}
});
showPopover();
});
},
inserted(el, binding, vnode){
}
}
+3
View File
@@ -0,0 +1,3 @@
import Vue from 'vue';
import Dropdown from './dropdown';
Vue.directive('dropdown',Dropdown);
+2 -1
View File
@@ -14,7 +14,8 @@ import lemonMessageEvent from "./components/message/event";
import LemonIMUI from "./components/index";
import "./styles/common/index.styl";
const version = "0.1";
import './directives';
const version = "1.4.2";
const components = [
LemonIMUI,
LemonContact,
+10 -7
View File
@@ -1,12 +1,15 @@
// @font-face {
// font-family: 'lemon-icons';
// src: url('//at.alicdn.com/t/font_1312162_neqltsj20an.eot');
// src: url('//at.alicdn.com/t/font_1312162_neqltsj20an.eot?#iefix') format('embedded-opentype'),
// url('//at.alicdn.com/t/font_1312162_neqltsj20an.woff2') format('woff2'),
// url('//at.alicdn.com/t/font_1312162_neqltsj20an.woff') format('woff'),
// url('//at.alicdn.com/t/font_1312162_neqltsj20an.ttf') format('truetype'),
// url('//at.alicdn.com/t/font_1312162_neqltsj20an.svg#iconfont') format('svg');
// }
@font-face {
font-family: 'lemon-icons';
src: url('//at.alicdn.com/t/font_1312162_neqltsj20an.eot');
src: url('//at.alicdn.com/t/font_1312162_neqltsj20an.eot?#iefix') format('embedded-opentype'),
url('//at.alicdn.com/t/font_1312162_neqltsj20an.woff2') format('woff2'),
url('//at.alicdn.com/t/font_1312162_neqltsj20an.woff') format('woff'),
url('//at.alicdn.com/t/font_1312162_neqltsj20an.ttf') format('truetype'),
url('//at.alicdn.com/t/font_1312162_neqltsj20an.svg#iconfont') format('svg');
src:url('../fonts/icon.woff') format('woff');
}
[class^='lemon-icon-'],
[class*=' lemon-icon-']
Binary file not shown.
+4 -1
View File
@@ -74,7 +74,10 @@ export function arrayIntersect(a, b) {
export function clearHtml(str){
return str.replace(/<.*?>/ig,"");
}
//清除字符串内的所有HTML标签,除了IMG
export function clearHtmlExcludeImg(str){
return str.replace(/<(?!img).*?>/ig, "");
}
export function error(text) {
throw new Error(text);
}