This commit is contained in:
satori 2022-01-31 14:21:50 +08:00
parent 2906012920
commit e3db4d2f29
5 changed files with 242 additions and 61 deletions

45
assets/js/socket.js Normal file
View File

@ -0,0 +1,45 @@
const that = {
controller: new Map(),
connection: null,
onclose: null,
onerror: null,
onopen: null,
onmessage: null,
delay: 0,
init: (link) => {
that.connection = new WebSocket(link)
that.connection.onopen = (event) => {
that.delay = 0
console.log("Open connection")
that.connection.send(JSON.stringify({ fm: "chat", data: `Link Start! ${that.delay}` }))
// 检查消息版本, 从最后时间向前查20条
// 当向上滚动时, 从本地最早时间向前查询20条
// 落日志与合并日志
if (that.onopen) that.onopen();
}
that.connection.onmessage = (event) => {
console.log("[message]", event.data)
let data = JSON.parse(event.data)
console.log(event.data, "xxxxxxxxxxxxxx")
let call = that.controller.get(data.fm)
if (call) call(data)
if (that.onmessage) that.onmessage();
}
that.connection.onclose = (event) => {
if (event.wasClean) {
console.log(`[close] code=${event.code} reason=${event.reason}`);
} else {
that.delay++
console.log(`[close] 连接中断${that.delay}第次, 尝试重连(延时${that.delay} s)`);
setTimeout(that.init(link), that.delay * 1000)
}
if (that.onclose) that.onclose()
};
that.connection.onerror = (error) => {
console.log(`[error] ${error.message}`);
if (that.onerror) that.onerror()
};
}
}
export default that

View File

@ -21,7 +21,11 @@ button
color: #ffffff color: #ffffff
border: none border: none
border-radius: .25rem border-radius: .25rem
cursor: pointer
padding-left: 1rem
padding-right: 1rem
min-height: 2rem
font-weight: 600
a a
text-decoration: none text-decoration: none
a:link //未访问的 a:link //未访问的

View File

@ -0,0 +1,50 @@
<template lang="pug">
.dialogue-list
.post(v-for="item in data", :key="item._id")
.left
.avatar
.right
.name Last
.message {{ item.data }}
</template>
<script>
export default {
props: ["data"],
};
</script>
<style lang="sass" scoped>
.dialogue-list
.post
display: flex
margin: 1rem 0
.left
justify-content: center
align-items: center
.avatar
width: 2rem
height: 2rem
background: #ccc
border-radius: 50%
margin: .5rem auto
.right
padding: 0 2rem
.name
color: #999
font-size: .8rem
.message
background: #ffffff
padding: 1rem
border-radius: 1rem
position: relative
&::before
content: ""
position: absolute
top: 10px
left: -1rem
border-top: 20px solid #ffffff
border-left: 1rem solid transparent
border-right: 1rem solid transparent
</style>

View File

@ -1,32 +1,56 @@
<template lang="pug"> <template lang="pug">
.main .main
header.header header.header
nav.navbar.main-width .circumscription
NuxtLink.navbar-logo(to="/") Kana .logo Kana
NuxtLink.navbar-item(to="/") 主页 nav.navbar
.expnone NuxtLink.navbar-item(to="/") 论坛
.navbar-user(v-if="account.online") NuxtLink.navbar-item(to="/docs") 文档
NuxtLink.userinfo(to="/account") NuxtLink.navbar-item(to="/chat") 聊天室
img.avatar(:src="account.avatar") .online
span.name {{ account.name }} .navbar-user(v-if="account.online")
.navbar-sign(v-else) NuxtLink.userinfo(to="/account")
NuxtLink.button(to="/account/signin") Signin img.avatar(:src="account.avatar")
NuxtLink.button(to="/account/create") Login span.name {{ account.name }}
.navbar-sign(v-else)
NuxtLink.button(to="/account/signin") Signin
NuxtLink.button(to="/account/create") Login
.websocket(:class="{ on: websocket }")
Nuxt Nuxt
footer.footer footer.footer
b Kana p
b Kana
.github
a(href="https://github.com/InvisibleFuture/kana")
span.fab.fa-github
</template> </template>
<script> <script>
import "assets/sass/main.sass"; import "@/assets/sass/main.sass";
import "assets/sass/default.sass"; import "@/assets/sass/default.sass";
import socket from "@/assets/js/socket.js";
export default { export default {
data: () => ({
websocket: false,
}),
computed: { computed: {
account() { account() {
return this.$store.state.account; return this.$store.state.account;
}, },
}, },
beforeMount() {
// 线, 线绿
socket.onclose = () => {
this.websocket = false;
};
socket.onopen = () => {
this.websocket = true;
};
let protocol = location.protocol === "https:" ? "wss:" : "ws:";
socket.init(`${protocol}//${location.host}/api/`);
},
mounted() { mounted() {
console.log( console.log(
"%c こめいじ さとり %c satori.love ", "%c こめいじ さとり %c satori.love ",
@ -39,57 +63,51 @@ export default {
</script> </script>
<style lang="sass"> <style lang="sass">
.block .websocket
padding-top: 10rem background: red
padding-bottom: 10rem border-radius: 50%
width: 1rem
height: 1rem
margin: .25rem .5rem
.websocket.on
background: green
@media (min-width: 480px) .main
.main-width >header.header>div
margin: 0 2rem
@media (min-width: 1280px)
.main-width
max-width: 1200px
margin: auto
header.header
//background-color: rgba(0, 0, 0, .8)
nav.navbar
display: flex display: flex
align-items: center align-items: flex-end
.navbar-logo padding-top: .5rem
//color: #fff >.logo
margin: 0 1rem font-size: 2rem
font-size: 1.2rem font-weight: 900
font-weight: 600 margin-right: 1.5rem
.navbar-item >nav.navbar
//color: #eee
padding: 1rem
font-size: 1.2rem
font-weight: 600
.navbar-item:hover
//color: #fff
.expnone
flex: 1 flex: 1
.userinfo
//color: #ffffff
font-weight: 600
display: flex display: flex
align-items: center align-items: center
.avatar //justify-content: center
width: 24px .navbar-item
height: 24px margin: 0 .25rem
border-radius: 50% padding: 0 .75rem
margin-right: .5rem height: 2rem
line-height: 2rem
text-align: center
font-weight: 600
>.online
.navbar-user
.userinfo
font-weight: 600
display: flex
align-items: center
.avatar
width: 24px
height: 24px
border-radius: 50%
margin-right: .5rem
footer.footer footer.footer
text-align: center text-align: center
margin: 4rem padding: 4rem
.github
a.button font-size: 2rem
border: none
border-radius: .25rem
padding: .5rem 1rem
margin: 1rem .5rem
background-color: #007bff
color: #ffffff
</style> </style>

64
pages/chat/index.vue Normal file
View File

@ -0,0 +1,64 @@
<template lang="pug">
.chat-index
.circumscription
p Chat 频道列表 {{ chatlist.length }}
ul(v-if="chatlist.length")
li(v-for="item in chatlist", :key="item._id")
p {{ item.name }}
button(@click="create") 创建频道
.ceremony
.circumscription
span chat
DialogueList(:data="chatactive")
textarea.dialogue(v-model="chat.data", rows="12")
button.submit(@click="submit") 发表
</template>
<script>
import socket from "@/assets/js/socket.js";
export default {
asyncData({ $axios }) {
return $axios("/api/chat").then((res) => {
return {
chatlist: res.data,
chat: { data: "" },
chatactive: [{ _id: "2333", data: "cacd" }],
};
});
},
mounted() {
socket.controller.set("chat", (data) => {
this.chatactive.push(data);
console.log(data);
});
},
methods: {
create() {
let data = { name: "FM DEMO", data: "23333" };
this.$axios.post("/api/chat", data).then((res) => {
console.log(res.data);
});
},
submit() {
socket.connection.send(
JSON.stringify({
fm: "chat",
data: this.chat.data,
})
);
this.chat.data = "";
},
},
};
</script>
<style lang="sass">
.chat-index
textarea.dialogue
width: 100%
padding: 1rem
border: 1px solid #eee
border-radius: .5rem
box-sizing: border-box
</style>