INIT
This commit is contained in:
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"presets": [
|
||||||
|
"@vue/app",
|
||||||
|
[
|
||||||
|
"@babel/preset-env",
|
||||||
|
{
|
||||||
|
"modules": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"plugins": [
|
||||||
|
[
|
||||||
|
"component",
|
||||||
|
{
|
||||||
|
"libraryName": "element-ui",
|
||||||
|
"styleLibraryName": "theme-chalk"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
> 1%
|
||||||
|
last 2 versions
|
||||||
|
not ie <= 8
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
module.exports = {
|
||||||
|
root: true,
|
||||||
|
env: {
|
||||||
|
node: true
|
||||||
|
},
|
||||||
|
extends: ["plugin:vue/essential", "@vue/prettier"],
|
||||||
|
rules: {
|
||||||
|
"no-console": process.env.NODE_ENV === "production" ? "error" : "off",
|
||||||
|
"no-debugger": process.env.NODE_ENV === "production" ? "error" : "off"
|
||||||
|
},
|
||||||
|
parserOptions: {
|
||||||
|
parser: "babel-eslint"
|
||||||
|
}
|
||||||
|
};
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
.DS_Store
|
||||||
|
node_modules
|
||||||
|
/dist
|
||||||
|
|
||||||
|
# local env files
|
||||||
|
.env.local
|
||||||
|
.env.*.local
|
||||||
|
|
||||||
|
# Log files
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
//监听聊天信息滚动到顶部
|
||||||
|
@pullingTop({pageNum,closePullTop})
|
||||||
|
//点击头像
|
||||||
|
@avatarClick
|
||||||
|
//点击信息内容
|
||||||
|
@messageClick
|
||||||
|
//点击信息状态
|
||||||
|
@statusClick
|
||||||
|
//文本框变化
|
||||||
|
@inputChange
|
||||||
|
|
||||||
|
//聚焦輸入框
|
||||||
|
inputBlur()
|
||||||
|
//更新消息
|
||||||
|
updateMessage(msgData)
|
||||||
|
//刪除消息
|
||||||
|
removeMessage(id)
|
||||||
|
//刪除全部消息
|
||||||
|
removeAllMessage()
|
||||||
|
//在底部增加消息
|
||||||
|
appendMessage([msgData])
|
||||||
|
//在顶部增加消息
|
||||||
|
prependMessage([msgData])
|
||||||
@@ -1,4 +1,8 @@
|
|||||||
|
<<<<<<< HEAD
|
||||||
# lemon-im
|
# lemon-im
|
||||||
|
=======
|
||||||
|
# flat-im
|
||||||
|
>>>>>>> INIT
|
||||||
|
|
||||||
#### Description
|
#### Description
|
||||||
{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**}
|
{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**}
|
||||||
|
|||||||
@@ -1,8 +1,45 @@
|
|||||||
|
<<<<<<< HEAD
|
||||||
# lemon-im
|
# lemon-im
|
||||||
|
|
||||||
#### 介绍
|
#### 介绍
|
||||||
{**以下是码云平台说明,您可以替换此简介**
|
{**以下是码云平台说明,您可以替换此简介**
|
||||||
码云是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台
|
码云是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台
|
||||||
|
=======
|
||||||
|
# flat-im
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
|
## Project setup
|
||||||
|
```
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
### Compiles and hot-reloads for development
|
||||||
|
```
|
||||||
|
npm run serve
|
||||||
|
```
|
||||||
|
|
||||||
|
### Compiles and minifies for production
|
||||||
|
```
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
### Run your tests
|
||||||
|
```
|
||||||
|
npm run test
|
||||||
|
```
|
||||||
|
|
||||||
|
### Lints and fixes files
|
||||||
|
```
|
||||||
|
npm run lint
|
||||||
|
```
|
||||||
|
|
||||||
|
### Customize configuration
|
||||||
|
See [Configuration Reference](https://cli.vuejs.org/config/).
|
||||||
|
=======
|
||||||
|
#### 介绍
|
||||||
|
{**以下是码云平台说明,您可以替换此简介**
|
||||||
|
码云是开源中国推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台
|
||||||
|
>>>>>>> INIT
|
||||||
无论是个人、团队、或是企业,都能够用码云实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)}
|
无论是个人、团队、或是企业,都能够用码云实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)}
|
||||||
|
|
||||||
#### 软件架构
|
#### 软件架构
|
||||||
@@ -36,4 +73,9 @@
|
|||||||
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解码云上的优秀开源项目
|
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解码云上的优秀开源项目
|
||||||
4. [GVP](https://gitee.com/gvp) 全称是码云最有价值开源项目,是码云综合评定出的优秀开源项目
|
4. [GVP](https://gitee.com/gvp) 全称是码云最有价值开源项目,是码云综合评定出的优秀开源项目
|
||||||
5. 码云官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
|
5. 码云官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
|
||||||
|
<<<<<<< HEAD
|
||||||
6. 码云封面人物是一档用来展示码云会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
|
6. 码云封面人物是一档用来展示码云会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
|
||||||
|
=======
|
||||||
|
6. 码云封面人物是一档用来展示码云会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
|
||||||
|
>>>>>>> 81b7591d59fe4d8d71e2902e65eedd796f943ffc
|
||||||
|
>>>>>>> INIT
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
<template>
|
||||||
|
<div id="app">
|
||||||
|
<lemon-im v-bind="IMData"
|
||||||
|
@pull-friends-message="pullFriendsMessage"></lemon-im>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "app",
|
||||||
|
data () {
|
||||||
|
this.friendData = {
|
||||||
|
"id": 1,
|
||||||
|
"diaplayName": "贤心",
|
||||||
|
"avatarPath": "a.jpg",
|
||||||
|
"sign": "这些都是测试数据,实际使用请严格按照该格式返回"
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
IMData: {
|
||||||
|
friends: [],
|
||||||
|
groups: [],
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted: function () {
|
||||||
|
setInterval(() => {
|
||||||
|
this.IMData.friends.push({ ...this.friendData })
|
||||||
|
this.friendData.id++
|
||||||
|
}, 1000)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
pullFriendsMessage (data, resolve, reject) {
|
||||||
|
resolve([{ ...this.friendData }])
|
||||||
|
//resolve([...this.friendData.id])
|
||||||
|
this.friendData.id++
|
||||||
|
},
|
||||||
|
pullGroups () {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="sass"></style>
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 6.7 KiB |
@@ -0,0 +1,114 @@
|
|||||||
|
<template>
|
||||||
|
<div class="hello">
|
||||||
|
<h1>{{ msg }}</h1>
|
||||||
|
<p>
|
||||||
|
For a guide and recipes on how to configure / customize this project,<br />
|
||||||
|
check out the
|
||||||
|
<a href="https://cli.vuejs.org" target="_blank" rel="noopener"
|
||||||
|
>vue-cli documentation</a
|
||||||
|
>.
|
||||||
|
</p>
|
||||||
|
<h3>Installed CLI Plugins</h3>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
>babel</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
>eslint</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<h3>Essential Links</h3>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://forum.vuejs.org" target="_blank" rel="noopener"
|
||||||
|
>Forum</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://chat.vuejs.org" target="_blank" rel="noopener"
|
||||||
|
>Community Chat</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://twitter.com/vuejs" target="_blank" rel="noopener"
|
||||||
|
>Twitter</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<h3>Ecosystem</h3>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="https://router.vuejs.org" target="_blank" rel="noopener"
|
||||||
|
>vue-router</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href="https://github.com/vuejs/vue-devtools#vue-devtools"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
>vue-devtools</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener"
|
||||||
|
>vue-loader</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href="https://github.com/vuejs/awesome-vue"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
>awesome-vue</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "HelloWorld",
|
||||||
|
props: {
|
||||||
|
msg: String
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||||
|
<style scoped lang="scss">
|
||||||
|
h3 {
|
||||||
|
margin: 40px 0 0;
|
||||||
|
}
|
||||||
|
ul {
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
li {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0 10px;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
color: #42b983;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import Vue from "vue";
|
||||||
|
import App from "./App.vue";
|
||||||
|
import LemonIM from "../packages";
|
||||||
|
Vue.use(LemonIM);
|
||||||
|
|
||||||
|
Vue.config.productionTip = false;
|
||||||
|
|
||||||
|
new Vue({
|
||||||
|
render: h => h(App)
|
||||||
|
}).$mount("#app");
|
||||||
Submodule
+1
Submodule lemon-im added at ad3c67e0d2
Generated
+12540
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"name": "lemon-im",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"serve": "vue-cli-service serve",
|
||||||
|
"build": "vue-cli-service build",
|
||||||
|
"lint": "vue-cli-service lint"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"element-ui": "^2.8.2",
|
||||||
|
"vue": "^2.6.10"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@vue/cli-plugin-babel": "^3.6.0",
|
||||||
|
"@vue/cli-plugin-eslint": "^3.6.0",
|
||||||
|
"@vue/cli-service": "^3.6.0",
|
||||||
|
"@vue/eslint-config-prettier": "^4.0.1",
|
||||||
|
"babel-eslint": "^10.0.1",
|
||||||
|
"babel-plugin-component": "^1.1.1",
|
||||||
|
"eslint": "^5.16.0",
|
||||||
|
"eslint-plugin-vue": "^5.0.0",
|
||||||
|
"node-sass": "^4.9.0",
|
||||||
|
"sass-loader": "^7.1.0",
|
||||||
|
"vue-template-compiler": "^2.5.21"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
<template>
|
||||||
|
<div class='lemon-contact-list'>
|
||||||
|
<div class="lemon-contact-item"
|
||||||
|
v-for="item in control.friends"
|
||||||
|
:key="item.id"
|
||||||
|
@click="control._changeMessageView(item)">
|
||||||
|
{{item.diaplayName}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'ContactList',
|
||||||
|
inject: ["control"],
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {},
|
||||||
|
watch: {},
|
||||||
|
methods: {
|
||||||
|
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang='scss'>
|
||||||
|
@import '~styles/utils/index';
|
||||||
|
@include b(contact-item) {
|
||||||
|
padding: 10px 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
&:hover {
|
||||||
|
background: #000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<template>
|
||||||
|
<div class=''>
|
||||||
|
LemonGroupList
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'GroupList',
|
||||||
|
components: {},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {},
|
||||||
|
watch: {},
|
||||||
|
methods: {
|
||||||
|
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang='scss'>
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,226 @@
|
|||||||
|
<template>
|
||||||
|
<el-container class="lemon-container lemon-container--center"
|
||||||
|
ref="container">
|
||||||
|
<el-aside class="lemon-sidebar"
|
||||||
|
width="240px">
|
||||||
|
<ul class="lemon-tab">
|
||||||
|
<li v-for="item in tabList"
|
||||||
|
:key="item.name"
|
||||||
|
:tab-name="item.name"
|
||||||
|
:class="['lemon-tab__item', item.name == currentTab && 'lemon-tab__item--active']"
|
||||||
|
@click="tabChange(item.name)">
|
||||||
|
<span :class="item.icon"></span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="lemon-tabview">
|
||||||
|
<div class="lemon-tabview__item"
|
||||||
|
v-for="item in tabList"
|
||||||
|
v-show="item.name == currentTab"
|
||||||
|
:key="item.name"
|
||||||
|
:tabview-name="item.name">
|
||||||
|
<component :is="item.componentName"
|
||||||
|
@changeMessageView="_changeMessageView"></component>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-aside>
|
||||||
|
<el-container class="lemon-main">
|
||||||
|
<el-header class="lemon-header"
|
||||||
|
height="48px">
|
||||||
|
宜宾劲越二手车市场(上江北) (500)
|
||||||
|
</el-header>
|
||||||
|
<el-main>
|
||||||
|
<lemon-message-view></lemon-message-view>
|
||||||
|
</el-main>
|
||||||
|
<el-main>工具欄</el-main>
|
||||||
|
</el-container>
|
||||||
|
</el-container>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import LemonContactList from '../contact-list'
|
||||||
|
import LemonGroupList from '../group-list'
|
||||||
|
import LemonMessageList from '../message-list'
|
||||||
|
import LemonMessageView from '../message-view'
|
||||||
|
const components = {
|
||||||
|
LemonContactList,
|
||||||
|
LemonGroupList,
|
||||||
|
LemonMessageList,
|
||||||
|
LemonMessageView
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'LemonIm',
|
||||||
|
components,
|
||||||
|
provide () {
|
||||||
|
return {
|
||||||
|
control: this
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
friends: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
groups: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
this.tabList = [{
|
||||||
|
name: 'message',
|
||||||
|
icon: 'el-icon-s-comment',
|
||||||
|
componentName: 'lemon-message-list',
|
||||||
|
}, {
|
||||||
|
name: 'contact',
|
||||||
|
icon: 'el-icon-user-solid',
|
||||||
|
componentName: 'lemon-contact-list',
|
||||||
|
}, {
|
||||||
|
name: 'group',
|
||||||
|
icon: 'el-icon-message-solid',
|
||||||
|
componentName: 'lemon-group-list',
|
||||||
|
}]
|
||||||
|
return {
|
||||||
|
//当前会话对象的ID 根据 currentTab
|
||||||
|
currentTab: 'contact',
|
||||||
|
//当前聊天用户ID 根据聊天类型不一样 代表用户ID 群组ID 讨论组ID
|
||||||
|
currentMessageId: null,
|
||||||
|
//聊天视图是否加载中
|
||||||
|
messageViewloading: true,
|
||||||
|
//群聊天记录 groupId => [message]
|
||||||
|
groupMessageData: {
|
||||||
|
|
||||||
|
},
|
||||||
|
//好友聊天记录 friendId => [message]
|
||||||
|
friendMessageData: {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
this._initialize()
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
//聊天窗口中的数据
|
||||||
|
messageViewData () {
|
||||||
|
return this.friendMessageData[this.currentMessageId]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {},
|
||||||
|
methods: {
|
||||||
|
//左侧选项卡切换
|
||||||
|
tabChange (name) {
|
||||||
|
this.currentTab = name;
|
||||||
|
this.findNode(`.lemon-tabview`).scrollTop = '0px'
|
||||||
|
},
|
||||||
|
//打开一个群组聊天窗口
|
||||||
|
openGroupMessageView (group) {
|
||||||
|
this._changeMessageViewComplete(group.id)
|
||||||
|
},
|
||||||
|
//打开普通聊天窗口
|
||||||
|
openFriendMessageView (friend) {
|
||||||
|
if (!this.friendMessageData[friend.id]) {
|
||||||
|
this.$emit('pull-friends-message', friend, (newData) => {
|
||||||
|
this._changeMessageViewComplete(friend.id)
|
||||||
|
this.friendMessageData[friend.id] = [...newData]
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this._changeMessageViewComplete(friend.id)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_changeMessageViewComplete (id) {
|
||||||
|
this.messageViewloading = false
|
||||||
|
this.currentMessageId = id
|
||||||
|
},
|
||||||
|
_changeMessageView (item) {
|
||||||
|
this.openFriendMessageView(item)
|
||||||
|
/**
|
||||||
|
const resolve = (newData) => {
|
||||||
|
this.messageViewloading = false
|
||||||
|
this.
|
||||||
|
}
|
||||||
|
const reject = () => {
|
||||||
|
this.messageViewloading = false
|
||||||
|
}
|
||||||
|
this.$emit('pullFriendsMessage', item, {
|
||||||
|
resolve,
|
||||||
|
reject
|
||||||
|
})
|
||||||
|
*/
|
||||||
|
},
|
||||||
|
_openMessageView () {
|
||||||
|
|
||||||
|
},
|
||||||
|
findNode (query) {
|
||||||
|
return this.$refs.container.$el.querySelector(query)
|
||||||
|
},
|
||||||
|
_initialize () {
|
||||||
|
|
||||||
|
},
|
||||||
|
//将左侧的滚动条重置到顶部
|
||||||
|
_tabviewScrollToTop () {
|
||||||
|
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang='scss'>
|
||||||
|
@import '~styles/utils/index';
|
||||||
|
body {
|
||||||
|
background: #8d9198;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include b(container) {
|
||||||
|
width: 900px;
|
||||||
|
height: 700px;
|
||||||
|
@include m(center) {
|
||||||
|
@include position-center(fixed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@include b(sidebar) {
|
||||||
|
background: #1f252d;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
color: #fff;
|
||||||
|
overflow: hidden;
|
||||||
|
.el-tabs--card {
|
||||||
|
.el-tabs__nav,
|
||||||
|
.el-tabs__item,
|
||||||
|
.el-tabs__header {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@include b(tab) {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
@include e(item) {
|
||||||
|
cursor: pointer;
|
||||||
|
line-height: 56px;
|
||||||
|
text-align: center;
|
||||||
|
flex: 1;
|
||||||
|
transition: all ease-in-out 0.3s;
|
||||||
|
font-size: 22px;
|
||||||
|
color: #6d6d6d;
|
||||||
|
@include m(active) {
|
||||||
|
color: #11d207;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@include b(tabview) {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
@include scrollbar-dark();
|
||||||
|
|
||||||
|
@include e(item) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@include b(main) {
|
||||||
|
background: #eceef1;
|
||||||
|
}
|
||||||
|
@include b(header) {
|
||||||
|
line-height: 48px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
<template>
|
||||||
|
<div class='lemon-message-list'>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'MessageList',
|
||||||
|
inject: ["control"],
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
|
||||||
|
};
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
},
|
||||||
|
computed: {},
|
||||||
|
watch: {},
|
||||||
|
methods: {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang='scss'>
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
<template>
|
||||||
|
<div class='lemon-message-view'
|
||||||
|
v-loading="control.messageViewloading"
|
||||||
|
element-loading-background="transparent">
|
||||||
|
{{ control.messageViewData }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'MessageView',
|
||||||
|
components: {},
|
||||||
|
inject: ["control"],
|
||||||
|
created () {
|
||||||
|
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
},
|
||||||
|
computed: {},
|
||||||
|
watch: {},
|
||||||
|
methods: {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang='scss'>
|
||||||
|
@import '~styles/utils/index';
|
||||||
|
@include b(message-view) {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import Vue from "vue";
|
||||||
|
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Icon,
|
||||||
|
Row,
|
||||||
|
Col,
|
||||||
|
Container,
|
||||||
|
Header,
|
||||||
|
Main,
|
||||||
|
Aside,
|
||||||
|
Loading
|
||||||
|
} from "element-ui";
|
||||||
|
Vue.use(Button);
|
||||||
|
Vue.use(Icon);
|
||||||
|
Vue.use(Row);
|
||||||
|
Vue.use(Col);
|
||||||
|
Vue.use(Container);
|
||||||
|
Vue.use(Header);
|
||||||
|
Vue.use(Main);
|
||||||
|
Vue.use(Aside);
|
||||||
|
Vue.use(Loading.directive);
|
||||||
|
|
||||||
|
Vue.prototype.$loading = Loading.service;
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import "./styles/common/index.scss";
|
||||||
|
import "./element-ui";
|
||||||
|
import Lemon from "./components/lemon";
|
||||||
|
const version = "0.1";
|
||||||
|
const components = [Lemon];
|
||||||
|
const install = (Vue, opts = {}) => {
|
||||||
|
components.forEach(component => {
|
||||||
|
Vue.component(component.name, component);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
if (typeof window !== "undefined" && window.Vue) {
|
||||||
|
install(window.Vue);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
version,
|
||||||
|
install
|
||||||
|
};
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
textMessage = {
|
||||||
|
msgId: "msgid",
|
||||||
|
status: "send_going",
|
||||||
|
msgType: "text",
|
||||||
|
isOutgoing: true,
|
||||||
|
text: "text",
|
||||||
|
fromUser: {},
|
||||||
|
extras: {}// option
|
||||||
|
}
|
||||||
|
|
||||||
|
imageMessage = {
|
||||||
|
msgId: "msgid",
|
||||||
|
msgType: "image",
|
||||||
|
isOutGoing: true,
|
||||||
|
mediaPath: "image path",
|
||||||
|
fromUser: {},
|
||||||
|
extras: {}// option
|
||||||
|
}
|
||||||
|
|
||||||
|
videoMessage = { // video message
|
||||||
|
msgId: "msgid",
|
||||||
|
status: "send_failed",
|
||||||
|
msgType: "video",
|
||||||
|
isOutGoing: true,
|
||||||
|
druation: number,
|
||||||
|
mediaPath: "voice path",
|
||||||
|
fromUser: {},
|
||||||
|
extras: {}// option
|
||||||
|
}
|
||||||
|
customMessage = { // custom message
|
||||||
|
msgId: "msgid",
|
||||||
|
msgType: "custom",
|
||||||
|
status: "send_failed",
|
||||||
|
isOutgoing: true,
|
||||||
|
contentSize: {height: 100, width: 100},
|
||||||
|
content: "<h1>custom message will render html string</h1>", // content is html format, avoid to use <script>
|
||||||
|
fromUser: {},
|
||||||
|
extras: {}// option
|
||||||
|
}
|
||||||
|
eventMessage = { // event message
|
||||||
|
msgId: "msgid",
|
||||||
|
msgType: "event",
|
||||||
|
text: "the event text"
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
@import './normalize';
|
||||||
+38
@@ -0,0 +1,38 @@
|
|||||||
|
/**
|
||||||
|
* 基本样式入口
|
||||||
|
*/
|
||||||
|
|
||||||
|
html {
|
||||||
|
-webkit-tap-highlight-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a,
|
||||||
|
input,
|
||||||
|
button,
|
||||||
|
textarea {
|
||||||
|
&:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ol,
|
||||||
|
ul {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
input,
|
||||||
|
button,
|
||||||
|
textarea {
|
||||||
|
font: inherit;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
@import './mixins';
|
||||||
|
@import './var';
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
//BEM
|
||||||
|
$fi-namespace: 'lemon';
|
||||||
|
|
||||||
|
@mixin b($block) {
|
||||||
|
$selector: $fi-namespace + '-' + $block;
|
||||||
|
.#{$selector} {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@mixin e($element) {
|
||||||
|
$selector: '__' + $element;
|
||||||
|
&#{$selector} {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@mixin m($modifier) {
|
||||||
|
$selector: '--' + $modifier;
|
||||||
|
&#{$selector} {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin bem($block, $element: false, $modifier: false) {
|
||||||
|
$selector: '.';
|
||||||
|
@if $block {
|
||||||
|
$selector: $fi-namespace + '-' + $block;
|
||||||
|
}
|
||||||
|
@if $element {
|
||||||
|
$selector: $selector + '__' + $element;
|
||||||
|
}
|
||||||
|
@if $modifier {
|
||||||
|
$selector: $selector + '--' + $modifier;
|
||||||
|
}
|
||||||
|
& .#{$selector} {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin user-select($value) {
|
||||||
|
-moz-user-select: $value;
|
||||||
|
-webkit-user-select: $value;
|
||||||
|
-ms-user-select: $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin scrollbar-theme($color: #1f252d, $background: #6d6d6d) {
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
width: 5px;
|
||||||
|
height: 5px;
|
||||||
|
}
|
||||||
|
&::-webkit-scrollbar-track-piece {
|
||||||
|
background-color: $background;
|
||||||
|
}
|
||||||
|
&::-webkit-scrollbar-thumb:vertical {
|
||||||
|
height: 5px;
|
||||||
|
background-color: $color;
|
||||||
|
}
|
||||||
|
&::-webkit-scrollbar-thumb:horizontal {
|
||||||
|
width: 5px;
|
||||||
|
background-color: $background;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@mixin scrollbar-dark() {
|
||||||
|
@include scrollbar-theme();
|
||||||
|
}
|
||||||
|
@mixin scrollbar-light() {
|
||||||
|
@include scrollbar-theme(#aaa, #fff);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin vertical-center {
|
||||||
|
$selector: &;
|
||||||
|
@at-root {
|
||||||
|
#{$selector}::after {
|
||||||
|
display: inline-block;
|
||||||
|
content: '';
|
||||||
|
height: 100%;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@mixin position-center($type: fixed) {
|
||||||
|
position: $type;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin ellipsis {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin arrow {
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
//$color-primary: #2977fa;
|
||||||
|
$color-primary: #1bc213;
|
||||||
|
$color-light: #fff;
|
||||||
|
/* 头像 */
|
||||||
|
$avatar-size: 45px;
|
||||||
|
$avatar-radius: 50%;
|
||||||
|
|
||||||
|
/** 标题 */
|
||||||
|
$title-background: $color-primary;
|
||||||
|
$title-color: $color-light;
|
||||||
|
$title-height: 44px;
|
||||||
|
/* 气泡 */
|
||||||
|
$bubble-background: $color-primary;
|
||||||
|
$bubble-color: $color-light;
|
||||||
|
$bubble-radius: 12px;
|
||||||
|
|
||||||
|
$bubble-self-background: #e7ebef;
|
||||||
|
$bubble-self-color: #606d84;
|
||||||
|
|
||||||
|
/* 输入框 */
|
||||||
|
$editor-textarea-height: 40px;
|
||||||
|
$editor-textarea-radius: 5px;
|
||||||
|
|
||||||
|
$editor-submit-disable-color: #bcbcbc;
|
||||||
|
$editor-submit-disable-background: #ebebeb;
|
||||||
|
$editor-submit-radius: $editor-textarea-radius;
|
||||||
|
/*
|
||||||
|
$bubble-self-background: #e7ebef;
|
||||||
|
$bubble-self-color: #3a465d;
|
||||||
|
*/
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export default function(a, b) {
|
||||||
|
return a.filter(x => b.includes(x));
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
module.exports = {
|
||||||
|
plugins: {
|
||||||
|
autoprefixer: {}
|
||||||
|
}
|
||||||
|
};
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
@@ -0,0 +1,23 @@
|
|||||||
|
<!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.0,maximum-scale=1.0, user-scalable=no"
|
||||||
|
/>
|
||||||
|
<link rel="icon" href="<%= BASE_URL %>favicon.ico" />
|
||||||
|
<title>在线客服</title>
|
||||||
|
</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>
|
||||||
|
<!-- built files will be auto injected -->
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
const path = require("path");
|
||||||
|
function resolve(dir) {
|
||||||
|
return path.join(__dirname, "", dir);
|
||||||
|
}
|
||||||
|
module.exports = {
|
||||||
|
pages: {
|
||||||
|
index: {
|
||||||
|
entry: "examples/main.js",
|
||||||
|
template: "public/index.html",
|
||||||
|
filename: "index.html"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
configureWebpack: {
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
components: resolve("packages/components"),
|
||||||
|
mixins: resolve("packages/mixins"),
|
||||||
|
styles: resolve("packages/styles"),
|
||||||
|
utils: resolve("packages/utils")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user