This commit is contained in:
min.jiang 2024-06-25 06:03:11 +08:00
parent 97709a8e50
commit f868969bde
31 changed files with 595 additions and 66 deletions

View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vite App</title>
<title>Freeleaps</title>
</head>
<body>
<div id="app"></div>

View File

@ -17,6 +17,7 @@
"pdfjs-dist": "^4.3.136",
"pinia": "^2.1.6",
"vue": "^3.3.4",
"vue-i18n": "^9.13.1",
"vue-router": "^4.2.4",
"vuex": "^4.1.0"
},

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -1,5 +1,7 @@
<template>
<div class="app-body">
<img src="@/assets/images/home-bg-left.png" alt="freeleaps" class="app-bg-left">
<img src="@/assets/images/home-bg-right.png" alt="freeleaps" class="app-bg-right">
<header class="body-header">
<router-view name="header"></router-view>
</header>
@ -34,6 +36,22 @@ export default {
margin-top: 0px;
}
.app-bg-left {
width: 300px;
position: fixed;
bottom: 0;
left: 0;
pointer-events: none;
}
.app-bg-right {
width: 300px;
position: fixed;
top: 0;
right: 0;
pointer-events: none;
}
.body-header {
width: 100%;
height: $header-height;

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -1 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 261.76 226.69"><path d="M161.096.001l-30.225 52.351L100.647.001H-.005l130.877 226.688L261.749.001z" fill="#41b883"/><path d="M161.096.001l-30.225 52.351L100.647.001H52.346l78.526 136.01L209.398.001z" fill="#34495e"/></svg>
<svg width="12" height="19" viewBox="0 0 12 19" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.56464 6.68937L0 9.35254L2.56464 12.0157L5.12928 9.35254L2.56464 6.68937Z" fill="#A4CBFA"/>
<path d="M5.78339 3.34465L3.21875 6.00781L5.78339 8.67098L8.34803 6.00781L5.78339 3.34465Z" fill="#5E8AF9"/>
<path d="M5.78729 10.0321L3.22266 12.6953L5.78729 15.3585L8.35193 12.6953L5.78729 10.0321Z" fill="#5E8AF9"/>
<path d="M9.00995 13.3798L6.44531 16.043L9.00995 18.7061L11.5746 16.043L9.00995 13.3798Z" fill="#1748F8"/>
<path d="M9.00214 6.68742L6.4375 9.35059L9.00214 12.0138L11.5668 9.35059L9.00214 6.68742Z" fill="#1748F8"/>
<path d="M9.00604 -7.86142e-05L6.44141 2.66309L9.00604 5.32625L11.5707 2.66309L9.00604 -7.86142e-05Z" fill="#1748F8"/>
</svg>

Before

Width:  |  Height:  |  Size: 276 B

After

Width:  |  Height:  |  Size: 757 B

View File

@ -44,6 +44,10 @@ $header-height: 88px;
$footer-height: 110px;
$body-height: calc(100vh - $header-height - $footer-height);
$body-width: 1288px;
$accordion-icon-width: 1rem;
$accordion-button-icon: url("data:image/svg+xml,<svg viewBox='0 0 1331 1024' xmlns='http://www.w3.org/2000/svg' width='64' height='64'><path d='M552.5504 896.512L45.1584 244.1216A102.4 102.4 0 0 1 125.952 78.848h1014.784a102.4 102.4 0 0 1 80.896 165.2736l-507.4944 652.288a102.4 102.4 0 0 1-161.6896 0z'></path></svg>");
$accordion-button-active-icon: url("data:image/svg+xml,<svg viewBox='0 0 1331 1024' xmlns='http://www.w3.org/2000/svg' width='64' height='64'><path d='M552.5504 896.512L45.1584 244.1216A102.4 102.4 0 0 1 125.952 78.848h1014.784a102.4 102.4 0 0 1 80.896 165.2736l-507.4944 652.288a102.4 102.4 0 0 1-161.6896 0z'></path></svg>");
// $default-font: "Lato", Verdana, Arial, sans-serif;
// $link-color: #ef899e;

View File

@ -179,6 +179,16 @@ p {
padding: 12px 28px 12px 12px;
outline: none;
box-shadow: none !important;
&::before {
content: '';
bottom: 0;
left: 50%;
width: 0;
height: 1px;
position: absolute;
background-color: #dee2e6;
transition: all 300ms ease-in-out;
}
.dashed-container {
flex: 1;
margin-right: 28px;
@ -191,7 +201,11 @@ p {
color: black;
background-color: transparent;
box-shadow: none;
border-bottom: 1px solid #dee2e6;
// border-bottom: 1px solid #dee2e6;
&::before {
left: 0;
width: 100%;;
}
.dashed-container {
background-color: #f3f6ff;
}
@ -232,3 +246,11 @@ p {
display: flex;
align-items: center;
}
input:-webkit-autofill {
box-shadow:0 0 0 1000px white inset !important;
}
input:-internal-autofill-previewed,
input:-internal-autofill-selected {
transition: background-color 5000s ease-in-out 0s !important;
}

View File

@ -237,7 +237,6 @@ export default {
getSelect() {
if (window.getSelection) {
let sel = window.getSelection()
console.log('this.selectedRange', sel)
if (sel.rangeCount > 0) {
return sel.getRangeAt(0)
}
@ -290,6 +289,7 @@ export default {
default:
console.log('none')
}
this.$refs.editor.blur()
// window.getSelection().removeAllRanges()
},
restoreSelection() {
@ -307,7 +307,9 @@ export default {
updateAction($event) {
let html = $event.target.innerHTML || ''
setTimeout(() => {
this.$emit('update:content', html)
});
}
}
}

View File

@ -0,0 +1,66 @@
<template>
<div class="laguage-switch-container">
<button class="btn btn-link btn-link-switch" data-bs-toggle="dropdown" aria-expanded="false" id="language-switch-button">
<img :src="languageMapper[currentLanguage]" alt="freeleap language">
</button>
<ul class="dropdown-menu" aria-labelledby="language-switch-button">
<template v-for="item in languageList" :key="item">
<li v-if="item != currentLanguage">
<button class="btn btn-link btn-link-switch" @click="changeLanguage(item)">
<img :src="languageMapper[item]" alt="freeleap zh">
</button>
</li>
</template>
</ul>
</div>
</template>
<script>
import zh_icon from '@/assets/lang/zh.png'
import en_icon from '@/assets/lang/us.png'
export default {
name: 'LaguageSwitch',
data() {
return {
languageList: ["zh", "en"],
languageMapper: {
"zh": zh_icon,
"en": en_icon
}
}
},
computed: {
currentLanguage() {
return this.$store.getters['basic/language']
}
},
methods: {
changeLanguage(l) {
this.$store.dispatch('basic/setLanguage', l)
}
}
}
</script>
<style lang="scss" scoped>
.laguage-switch-container {
display: inline;
position: relative;
.btn-link-switch {
padding: 0;
width: 35px;
line-height: 1;
img {width: 100%;}
}
.dropdown-menu {
min-width: auto;
margin-left: -5px !important;
.btn-link-switch {
padding: 0 5px;
width: 45px;
}
}
}
</style>

View File

@ -87,5 +87,8 @@ export default {
right: 0;
top: 0;
}
canvas {
width: 100%;
}
}
</style>

View File

@ -13,20 +13,22 @@
>
</div> -->
<div class="public-sites">
<button class="public-site-button" @click="gotoAbout()">About</button>
<button class="public-site-button" @click="gotoBlogs()">Blogs</button>
<button class="public-site-button" @click="gotoCareer()">Career</button>
<button class="public-site-button" @click="gotoContact()">
{{ getContactText }}
</button>
<button class="public-site-button" @click="gotoAbout()">{{ $t('About') }}</button>
<button class="public-site-button" @click="gotoBlogs()">{{ $t('Blogs') }}</button>
<button class="public-site-button" @click="gotoCareer()">{{ $t('Career') }}</button>
<button class="public-site-button" @click="gotoContact()">{{ $t('Contact') }}</button>
<laguage-switch />
</div>
</div>
</div>
</template>
<script>
import LaguageSwitch from '@/components/LaguageSwitch.vue'
// import { i18n } from '@/lang'
// const { t } = i18n.global
export default {
name: 'HeaderGuest',
components: {},
components: { LaguageSwitch },
computed: {
getContactText() {
if (this.getRegion === 'CN') {
@ -44,6 +46,9 @@ export default {
}
},
methods: {
// translate(content) {
// return i18n.global.t(content)
// },
gotoFrontdoor() {
this.mnx_navToFrontDoor()
},

View File

@ -4,7 +4,7 @@
<div
class="information-bar"
@click="gotoMessages"
:class="activePath == 'message' ? 'active' : ''"
:class="{'active' : activePath == 'message', 'unread' : unreadCount > 0}"
>
<img alt="freeleaps logo" src="@/assets/message.png" />
</div>
@ -56,6 +56,7 @@
Please go to profile page to add money receiving method
</div>
</div>
<laguage-switch class="laguage-switch" />
</div>
<div class="profile-container">
<img
@ -87,15 +88,21 @@
</template>
<script>
import { UserAuthApi } from '@/utils/backend/index'
import LaguageSwitch from '@/components/LaguageSwitch.vue'
export default {
name: 'HeaderGuest',
components: {},
computed: {},
components: { LaguageSwitch },
computed: {
unreadCount() {
return this.$store.getters['basic/unreadCount']
}
},
created() {
if (this.userIdentityNote.length > 8) {
this.userIdentityNote = this.userIdentityNote.slice(0, 5) + '...'
}
this.$store.dispatch('basic/initWebsocket', this.mnx_getUserAuthToken())
},
data() {
return {
@ -157,6 +164,9 @@ export default {
</script>
<style scoped lang="scss">
.laguage-switch {
margin-left: 30px;
}
.header-container {
width: 100%;
height: 100%;
@ -191,7 +201,7 @@ export default {
&::after {
content: '';
display: block;
display: none;
width: 8px;
height: 8px;
border-radius: 4px;
@ -201,6 +211,10 @@ export default {
background-color: #f44837;
}
&.unread::after {
display: block;
}
&.active {
border: 1px solid $primary;
}
@ -244,7 +258,7 @@ export default {
position: absolute;
background-color: white;
left: 0;
bottom: -20px;
bottom: -24px;
font-size: 12px;
color: #3d455f;
white-space: nowrap;

6
frontend/src/lang/en.js Normal file
View File

@ -0,0 +1,6 @@
export default {
"About": "About",
"Blogs": "Blogs",
"Career": "Career",
"Contact": "Contact",
}

View File

@ -0,0 +1,32 @@
import { createI18n } from 'vue-i18n'
import en from './en'
import zh from './zh'
const messages = { en, zh }
const getDefaultLocale = () => {
let defaultLanguage = localStorage.getItem('language')
if (defaultLanguage) {
return defaultLanguage
}
const lan = (navigator.browserLanguage || navigator.language).toLowerCase()
if (lan.indexOf('zh') > -1) {
defaultLanguage = 'zh'
} else if (lan.indexOf('en') > -1) {
defaultLanguage = 'en'
}
return defaultLanguage || 'zh'
}
const localeData = {
globalInjection: true,
legacy: false,
locale: getDefaultLocale(),
messages
}
export const i18n = createI18n(localeData)
export const setupI18n = {
install(app) {
app.use(i18n)
}
}

3
frontend/src/lang/zh.js Normal file
View File

@ -0,0 +1,3 @@
export default {
"Contact": "联系我们"
}

View File

@ -5,6 +5,7 @@ import { store, router } from './plugins/index'
import { navigatorMixin, userIdentityMixin, errorHanlderMixin, userAuthMixin } from './mixins/index'
import { tooltip } from './utils/index'
import { setupI18n } from '@/lang'
/* import the fontawesome core */
// import { library } from '@fortawesome/fontawesome-svg-core'
/* import font awesome icon component */
@ -31,6 +32,7 @@ import { tooltip } from './utils/index'
const app = createApp(App)
app.use(store)
app.use(router)
app.use(setupI18n)
app.mixin(userIdentityMixin)
app.mixin(navigatorMixin)
app.mixin(errorHanlderMixin)

View File

@ -40,6 +40,7 @@ import {
import { signinActionEnum } from '@/types/index'
export default {
components: {},
name: 'FrontDoor',
props: {},
data() {

View File

@ -6,9 +6,10 @@
:key="index"
@click="view_link(directory)"
>
<p>{{ directory.title_text }}</p>
<img class="directory_cover_image" :src="directory.cover_picture" />
<p>{{ directory.summary_text }}</p>
<p class="directory-title">{{ directory.title_text }}</p>
<p class="directory-subtitle">{{ directory.summary_text }}</p>
<button class="btn btn-link">Read More</button>
</div>
</div>
</template>
@ -46,13 +47,34 @@ export default {
<style scoped lang="scss">
.directories_containter {
@extend .container;
padding: 56px 40px;
}
.directory_container {
@extend .container;
padding: 0;
cursor: pointer;
text-align: left;
.btn-link {
margin-bottom: 24px;
text-decoration: underline;
padding: 0;
}
}
.directory_cover_image {
height: 20vh;
width: 100%;
border-radius: 16px;
margin-bottom: 16px;
}
.directory-title {
font-size: 48px;
// font-weight: bold;
color: #18181A;
margin-bottom: 5px;
}
.directory-subtitle {
font-size: 14px;
color: #666666;
}
</style>

View File

@ -48,14 +48,20 @@ export default {
<style scoped lang="scss">
.blogs_containter {
@extend .container;
padding: 56px 40px;
}
.blog_containter {
@extend .container;
cursor: pointer;
padding: 0;
h2, p {
text-align: left;
}
}
.blog_cover_image {
height: 20vh;
height: 311px;
}
</style>

View File

@ -1,19 +1,15 @@
<template>
<div class="directories_containter">
<div class="career_containter">
<div
class="directory_container"
class="career-item"
v-for="(directory, index) in directories"
:key="index"
@click="view_link(directory)"
>
<p
class="directory_title_txt"
v-tooltip
:title="directory.summary_text"
delay='{"show":"500", "hide":"100"}'
>
<u>{{ directory.title_text }}</u>
<p class="career-title">
{{ directory.title_text }}
</p>
<p>{{ directory.summary_text }}</p>
</div>
</div>
</template>
@ -48,15 +44,25 @@ export default {
}
</script>
<style scoped lang="scss">
.directories_containter {
.career_containter {
@extend .container;
}
max-width: 1000px;
.directory_container {
@extend .container;
.career-item {
cursor: pointer;
}
box-shadow: 0px 0px 24px 0px #D4D3E380;
padding: 32px;
color: #18181A;
font-size: 14px;
background-color: white;
margin-bottom: 32px;
text-align: left;
.directory_title_txt {
p {margin: 0;}
.career-title {
font-size: 32px;
margin-bottom: 10px;
}
}
}
</style>

View File

@ -1,8 +1,14 @@
<template>
<div class="directories_containter">
<div class="directory_container" v-for="(directory, index) in directories" :key="index">
<img class="directory_cover_image" :src="directory.cover_picture" />
<div v-html="directory.content_html"></div>
<div class="contact-container">
<div class="contact-item" v-for="(directory, index) in directories" :key="index">
<div class="contact-left">
<img :src="directory.cover_picture" />
<div class="contact-left-content">
<p class="contact-title-text">{{ directory.title_text }}</p>
<p>{{ directory.summary_text }}</p>
</div>
</div>
<div class="contact-right" v-html="directory.content_html"></div>
</div>
</div>
</template>
@ -34,6 +40,61 @@ export default {
}
</script>
<style scoped lang="scss">
.contact-container {
display: flex;
padding: 42px;
flex-direction: column;
justify-content: center;
align-items: center;
.contact-item {
display: flex;
flex-direction: row;
margin-bottom: 62px;
.contact-left {
border-radius: 12px;
background-color: $primary;
display: flex;
flex-direction: column;
overflow: hidden;
width: 368px;
img {
width: 100%;
}
.contact-left-content {
padding: 32px;
display: flex;
flex-direction: column;
text-align: left;
color: white;
flex: 1;
font-size: 14px;
justify-content: center;
p {
margin-bottom: 0;
}
.contact-title-text {
font-size: 32px;
}
}
}
.contact-right {
margin-left: 24px;
box-shadow: 0px 0px 24px 0px #D4D3E380;
background: white;
padding: 32px;
color: #18181A;
border-radius: 12px;
width: 368px;
text-align: left;
}
}
}
.directories_containter {
@extend .container;
}

View File

@ -1,6 +1,148 @@
<template>
<div>
<p>History</p>
<div class="history-container">
<div class="history-content">
<div class="accordion accordion-list" id="accordion-history-total">
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="collapse-history-total" aria-expanded="false" aria-controls="collapse-history-total">
<div class="history-bar dashed-container">
<div class="history-bar-container">
<div class="history-bar-item">
<label class="history-item-label">Total earning</label>
<p class="history-item-text">2000USD</p>
</div>
<div class="history-bar-item">
<label class="history-item-label">Paid</label>
<p class="history-item-text">2000USD</p>
</div>
<div class="history-bar-item">
<label class="history-item-label">Payable</label>
<p class="history-item-text">2000USD</p>
</div>
<div class="history-bar-item">
<label class="history-item-label">Total spending</label>
<p class="history-item-text">2000USD</p>
</div>
<div class="history-bar-item">
<label class="history-item-label">Deposit</label>
<p class="history-item-text">2000USD</p>
</div>
</div>
</div>
</button>
</h2>
<div id="collapse-history-total" class="accordion-collapse collapse" data-bs-parent="#accordion-history-total">
<div class="accordion-body">
</div>
</div>
</div>
</div>
<div class="accordion accordion-list" id="accordion-history-total">
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="collapse-history-total" aria-expanded="false" aria-controls="collapse-history-total">
<div class="history-bar dashed-container">
<div class="history-bar-container">
<div class="history-bar-item">
<label class="history-item-label">Summary</label>
<p class="history-item-text">Need a python programmer</p>
</div>
<div class="history-bar-item">
<label class="history-item-label">Spending</label>
<p class="history-item-text">2000USD</p>
</div>
<div class="history-bar-item">
<label class="history-item-label">Updated</label>
<p class="history-item-text">2023-10-19</p>
</div>
</div>
</div>
</button>
</h2>
<div id="collapse-history-total" class="accordion-collapse collapse" data-bs-parent="#accordion-history-total">
<div class="accordion-body">
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="collapse-history-total" aria-expanded="false" aria-controls="collapse-history-total">
<div class="history-bar dashed-container">
<div class="history-bar-container">
<div class="history-bar-item">
<label class="history-item-label">Summary</label>
<p class="history-item-text">Need a python programmer</p>
</div>
<div class="history-bar-item">
<label class="history-item-label">Spending</label>
<p class="history-item-text">2000USD</p>
</div>
<div class="history-bar-item">
<label class="history-item-label">Updated</label>
<p class="history-item-text">2023-10-19</p>
</div>
</div>
</div>
</button>
</h2>
<div id="collapse-history-total" class="accordion-collapse collapse" data-bs-parent="#accordion-history-total">
<div class="accordion-body">
</div>
</div>
</div>
</div>
<div class="accordion accordion-list" id="accordion-history-earning">
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapse-history-earning" aria-expanded="false" aria-controls="collapse-history-earning">
<div class="history-bar dashed-container">
<div class="history-bar-container">
<div class="history-bar-item">
<label class="history-item-label">Summary</label>
<p class="history-item-text">Need a python programmer</p>
</div>
<div class="history-bar-item">
<label class="history-item-label">Earining</label>
<p class="history-item-text">2000USD</p>
</div>
<div class="history-bar-item">
<label class="history-item-label">Updated</label>
<p class="history-item-text">2023-10-19</p>
</div>
</div>
</div>
</button>
</h2>
<div id="collapse-history-earning" class="accordion-collapse collapse" data-bs-parent="#accordion-history-earning">
<div class="accordion-body">
<div class="history-bar dashed-container">
<div class="history-bar-container">
<div class="history-bar-item">
<label class="history-item-label">Summary</label>
<p class="history-item-text">Need a python programmer</p>
</div>
<div class="history-bar-item">
<label class="history-item-label">Earining</label>
<p class="history-item-text">2000USD</p>
</div>
<div class="history-bar-item">
<label class="history-item-label">Updated</label>
<p class="history-item-text">2023-10-19</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
@ -30,3 +172,43 @@ export default {
}
}
</script>
<style lang="scss" scoped>
.history-container {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
.history-content {
width: 100%;
max-width: $body-width;
padding: 24px 0;
.history-bar {
display: flex;
align-items: center;
.history-bar-container {
@extend .flex-row-container;
@extend .flex-grow-1;
padding: 0;
}
.history-bar-item {
@extend .text-start;
@extend .flex-grow-1;
.history-item-label {
@extend .label-text-light;
}
.history-item-text {
@extend .text-start;
margin-bottom: 0;
font-weight: bold;
}
}
}
}
}
</style>

View File

@ -1008,8 +1008,8 @@ export default {
.project-item-text {
@extend .text-start;
@extend .mx-1;
margin-bottom: 0;
font-weight: bold;
}
.project-request-container {
@ -1067,7 +1067,6 @@ export default {
.request-proposal-content-container {
@extend .container;
@extend .border;
}
.request-proposal-content {
@ -1076,7 +1075,10 @@ export default {
.request-proposal-payment-plan {
@extend .container;
@extend .border;
border: 1px dashed #9CB0F6;
border-radius: 3px;
padding: 24px;
margin: 32px 0;
}
.request-proposal-payment-plan-stage-container {

View File

@ -147,21 +147,8 @@
</button>
</div>
<div class="description-container">
<!-- <div
class="input-description"
id="inputDescription"
placeholder="Fill the request's description here"
v-html="content"
@keyup="textAreaAdjust($event)"
@blur="descriptionDone($event)"
contenteditable="true"
/> -->
<freeleaps-editor v-model:content="content" />
</div>
<!-- <div class="file-upload-container">
<label for="file-upload" class="file-upload-label">Upload File:</label>
<input type="file" id="file-upload" class="file-upload-input" @change="handleFileUpload" />
</div> -->
<div class="action-footer">
<button class="cancel-button" @click="back">Cancel</button>
<button class="submit-button" @click="submit">(Re)Submit</button>
@ -347,9 +334,9 @@ export default {
.request-issue-container {
@extend .flex-colum-container;
box-shadow: 0px 0px 24px 0px rgba(212, 211, 227, 0.5);
border-top-left-radius: 12px;
border-top-right-radius: 12px;
border-radius: 12px;
overflow: hidden;
background: white
}
.action-bar {

View File

@ -0,0 +1,75 @@
/* eslint-disable no-prototype-builtins */
import { i18n } from '@/lang'
import { WsConnectionFactory } from '@/utils/backend/websocket'
const basicStore = {
namespaced: true,
state() {
return {
language: 'zh',
unreadCountMapper: [],
downstream_web_socket: null,
}
},
mutations: {
setLanguage(state, language) {
state.language = language
i18n.global.locale.value = language
localStorage.setItem('language', language)
},
initWebsocket(state, token) {
state.downstream_web_socket = WsConnectionFactory.CreateWebSocket(
token,
() => {
// keep
setInterval(() => {
state.downstream_web_socket.send(1)
}, 1000 * 60)
console.log('downstream_web_socket open')
},
(e) => {
const data = JSON.parse(e.data)
let unread = state.unreadCountMapper[data.sender_id]
if (unread) {
unread ++
} else {
unread = 1
}
state.unreadCountMapper[data.sender_id] = unread
console.log('downstream_web_socket onmessage: ', data, state.unreadCountMapper)
},
() => {
console.log('downstream_web_socket error')
},
() => {
console.log('downstream_web_socket closed')
}
)
}
},
actions: {
setLanguage(context, language) {
context.commit('setLanguage', language)
},
initWebsocket(context, token) {
context.commit('initWebsocket', token)
}
},
getters: {
language(state) {
return state.language
},
unreadCount(state) {
let count = 0
for (let key in state.unreadCountMapper) {
if (state.unreadCountMapper.hasOwnProperty(key)) {
count += state.unreadCountMapper[key]
}
}
return count
}
}
}
export { basicStore }

View File

@ -2,11 +2,13 @@
import { createStore } from 'vuex'
import { userAuthStore } from './userAuth'
import { userRoleEnum, userProfileStore } from './userProfile'
import { basicStore } from './basic'
const store = createStore({
modules: {
userAuth: userAuthStore,
userProfile: userProfileStore
userProfile: userProfileStore,
basic: basicStore
}
})

View File

@ -1,8 +1,8 @@
import { userUtils } from '../store/index'
// import { userUtils } from '../store/index'
class WsConnectionFactory {
static CreateWebSocket(onOpen, onMessage, onError, onClose) {
let jwt = userUtils.getJwtToken()
static CreateWebSocket(jwt, onOpen, onMessage, onError, onClose) {
// let jwt = userUtils.getJwtToken()
this.socket = new WebSocket(`/ws/downstream/online_platform_notification?token=${jwt}`)
this.socket.onopen = onOpen
this.socket.onmessage = onMessage