Showing
8 changed files
with
253 additions
and
10 deletions
| ... | @@ -23,13 +23,19 @@ declare module '@vue/runtime-core' { | ... | @@ -23,13 +23,19 @@ declare module '@vue/runtime-core' { |
| 23 | SvgIcon: typeof import('./src/components/Floor/svgIcon.vue')['default'] | 23 | SvgIcon: typeof import('./src/components/Floor/svgIcon.vue')['default'] |
| 24 | VanButton: typeof import('vant/es')['Button'] | 24 | VanButton: typeof import('vant/es')['Button'] |
| 25 | VanCol: typeof import('vant/es')['Col'] | 25 | VanCol: typeof import('vant/es')['Col'] |
| 26 | + VanConfigProvider: typeof import('vant/es')['ConfigProvider'] | ||
| 26 | VanDialog: typeof import('vant/es')['Dialog'] | 27 | VanDialog: typeof import('vant/es')['Dialog'] |
| 27 | VanField: typeof import('vant/es')['Field'] | 28 | VanField: typeof import('vant/es')['Field'] |
| 29 | + VanFloatingPanel: typeof import('vant/es')['FloatingPanel'] | ||
| 28 | VanIcon: typeof import('vant/es')['Icon'] | 30 | VanIcon: typeof import('vant/es')['Icon'] |
| 29 | VanImage: typeof import('vant/es')['Image'] | 31 | VanImage: typeof import('vant/es')['Image'] |
| 30 | VanOverlay: typeof import('vant/es')['Overlay'] | 32 | VanOverlay: typeof import('vant/es')['Overlay'] |
| 31 | VanPopup: typeof import('vant/es')['Popup'] | 33 | VanPopup: typeof import('vant/es')['Popup'] |
| 32 | VanRow: typeof import('vant/es')['Row'] | 34 | VanRow: typeof import('vant/es')['Row'] |
| 35 | + VanSwipe: typeof import('vant/es')['Swipe'] | ||
| 36 | + VanSwipeItem: typeof import('vant/es')['SwipeItem'] | ||
| 37 | + VanTab: typeof import('vant/es')['Tab'] | ||
| 38 | + VanTabs: typeof import('vant/es')['Tabs'] | ||
| 33 | VRViewer: typeof import('./src/components/VRViewer/index.vue')['default'] | 39 | VRViewer: typeof import('./src/components/VRViewer/index.vue')['default'] |
| 34 | } | 40 | } |
| 35 | } | 41 | } | ... | ... |
| ... | @@ -2,7 +2,7 @@ | ... | @@ -2,7 +2,7 @@ |
| 2 | * @Author: hookehuyr hookehuyr@gmail.com | 2 | * @Author: hookehuyr hookehuyr@gmail.com |
| 3 | * @Date: 2022-05-26 23:52:36 | 3 | * @Date: 2022-05-26 23:52:36 |
| 4 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 4 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 5 | - * @LastEditTime: 2023-08-07 13:32:25 | 5 | + * @LastEditTime: 2024-09-18 10:48:23 |
| 6 | * @FilePath: /map-demo/src/App.vue | 6 | * @FilePath: /map-demo/src/App.vue |
| 7 | * @Description: | 7 | * @Description: |
| 8 | --> | 8 | --> | ... | ... |
| 1 | /* | 1 | /* |
| 2 | * @Date: 2023-05-29 11:10:19 | 2 | * @Date: 2023-05-29 11:10:19 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2024-09-15 11:46:59 | 4 | + * @LastEditTime: 2024-09-18 09:38:42 |
| 5 | * @FilePath: /map-demo/src/route.js | 5 | * @FilePath: /map-demo/src/route.js |
| 6 | * @Description: 文件描述 | 6 | * @Description: 文件描述 |
| 7 | */ | 7 | */ |
| ... | @@ -62,4 +62,11 @@ export default [ | ... | @@ -62,4 +62,11 @@ export default [ |
| 62 | title: '扫描', | 62 | title: '扫描', |
| 63 | }, | 63 | }, |
| 64 | }, | 64 | }, |
| 65 | + { | ||
| 66 | + path: '/bieyuan/info', | ||
| 67 | + component: () => import('@/views/bieyuan/info.vue'), | ||
| 68 | + meta: { | ||
| 69 | + title: '详情页', | ||
| 70 | + }, | ||
| 71 | + }, | ||
| 65 | ]; | 72 | ]; | ... | ... |
src/views/bieyuan/info.vue
0 → 100644
| 1 | +<!-- | ||
| 2 | + * @Date: 2024-09-15 22:08:49 | ||
| 3 | + * @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 4 | + * @LastEditTime: 2024-09-18 14:17:43 | ||
| 5 | + * @FilePath: /map-demo/src/views/bieyuan/info.vue | ||
| 6 | + * @Description: 文件描述 | ||
| 7 | +--> | ||
| 8 | +<template> | ||
| 9 | + <div class="info-page"> | ||
| 10 | + <div> | ||
| 11 | + <van-config-provider :theme-vars="themeVars"> | ||
| 12 | + <van-swipe class="my-swipe" indicator-color="#DD7850" lazy-render :autoplay="5000"> | ||
| 13 | + <van-swipe-item v-for="image in images" :key="image"> | ||
| 14 | + <van-image fit="cover" width="100%" height="15rem" :src="image" /> | ||
| 15 | + </van-swipe-item> | ||
| 16 | + </van-swipe> | ||
| 17 | + </van-config-provider> | ||
| 18 | + </div> | ||
| 19 | + <div class="info-content-wrapper"> | ||
| 20 | + <div class="info-header"> | ||
| 21 | + <div> | ||
| 22 | + <p class="info-title">选佛场</p> | ||
| 23 | + <p class="info-sub-title">南楼2层</p> | ||
| 24 | + </div> | ||
| 25 | + <div class="info-btn">前往</div> | ||
| 26 | + </div> | ||
| 27 | + <div class="van-hairline--bottom"> | ||
| 28 | + <van-tabs v-model:active="active" color="#DD7850" title-active-color="#DD7850" sticky> | ||
| 29 | + <van-tab title="介 绍"> | ||
| 30 | + <div class="info-content"> | ||
| 31 | + Lorem ipsum dolor sit amet consectetur, adipisicing elit. Odit non, qui ullam placeat possimus laboriosam sequi a omnis debitis enim, rerum distinctio! Perspiciatis unde explicabo officiis sed nemo reprehenderit impedit? | ||
| 32 | + Lorem ipsum dolor sit amet consectetur, adipisicing elit. Odit non, qui ullam placeat possimus laboriosam sequi a omnis debitis enim, rerum distinctio! Perspiciatis unde explicabo officiis sed nemo reprehenderit impedit? | ||
| 33 | + Lorem ipsum dolor sit amet consectetur, adipisicing elit. Odit non, qui ullam placeat possimus laboriosam sequi a omnis debitis enim, rerum distinctio! Perspiciatis unde explicabo officiis sed nemo reprehenderit impedit? | ||
| 34 | + Lorem ipsum dolor sit amet consectetur, adipisicing elit. Odit non, qui ullam placeat possimus laboriosam sequi a omnis debitis enim, rerum distinctio! Perspiciatis unde explicabo officiis sed nemo reprehenderit impedit? | ||
| 35 | + Lorem ipsum dolor sit amet consectetur, adipisicing elit. Odit non, qui ullam placeat possimus laboriosam sequi a omnis debitis enim, rerum distinctio! Perspiciatis unde explicabo officiis sed nemo reprehenderit impedit? | ||
| 36 | + Lorem ipsum dolor sit amet consectetur, adipisicing elit. Odit non, qui ullam placeat possimus laboriosam sequi a omnis debitis enim, rerum distinctio! Perspiciatis unde explicabo officiis sed nemo reprehenderit impedit? | ||
| 37 | + Lorem ipsum dolor sit amet consectetur, adipisicing elit. Odit non, qui ullam placeat possimus laboriosam sequi a omnis debitis enim, rerum distinctio! Perspiciatis unde explicabo officiis sed nemo reprehenderit impedit? | ||
| 38 | + Lorem ipsum dolor sit amet consectetur, adipisicing elit. Odit non, qui ullam placeat possimus laboriosam sequi a omnis debitis enim, rerum distinctio! Perspiciatis unde explicabo officiis sed nemo reprehenderit impedit? | ||
| 39 | + Lorem ipsum dolor sit amet consectetur, adipisicing elit. Odit non, qui ullam placeat possimus laboriosam sequi a omnis debitis enim, rerum distinctio! Perspiciatis unde explicabo officiis sed nemo reprehenderit impedit? | ||
| 40 | + Lorem ipsum dolor sit amet consectetur, adipisicing elit. Odit non, qui ullam placeat possimus laboriosam sequi a omnis debitis enim, rerum distinctio! Perspiciatis unde explicabo officiis sed nemo reprehenderit impedit? | ||
| 41 | + </div> | ||
| 42 | + </van-tab> | ||
| 43 | + <van-tab title="故 事"></van-tab> | ||
| 44 | + <van-tab title="体 验"> | ||
| 45 | + <div style="padding: 1rem;"> | ||
| 46 | + <div style="color: #DD7850;">• 静心咖啡</div> | ||
| 47 | + <div style="color: #47525F; margin-top: 1rem;">静心咖啡绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍</div> | ||
| 48 | + </div> | ||
| 49 | + <div class="audio-wrapper"> | ||
| 50 | + <div @click="playAudio(item, index)" :class="['audio-item', play_audio_index === index ? 'click' : '']" v-for="(item, index) in audioList" :key="index"> | ||
| 51 | + <div>{{ item.text }}</div> | ||
| 52 | + <div :class="['audio-icon', play_audio_index === index ? 'click' : '']"></div> | ||
| 53 | + </div> | ||
| 54 | + </div> | ||
| 55 | + <div style="width: 100%;"> | ||
| 56 | + <img src="https://cdn.ipadbiz.cn/bieyuan/map/xcx.png" style="width: 100%;"> | ||
| 57 | + </div> | ||
| 58 | + </van-tab> | ||
| 59 | + </van-tabs> | ||
| 60 | + </div> | ||
| 61 | + </div> | ||
| 62 | + <div style="display: flex; justify-content: center; margin: 2rem 0;"> | ||
| 63 | + <van-image | ||
| 64 | + width="3rem" | ||
| 65 | + height="3rem" | ||
| 66 | + fit="contain" | ||
| 67 | + src="https://cdn.ipadbiz.cn/bieyuan/map/icon/scan_logo.png" | ||
| 68 | + /> | ||
| 69 | + </div> | ||
| 70 | + </div> | ||
| 71 | +</template> | ||
| 72 | + | ||
| 73 | +<script setup> | ||
| 74 | +import { ref } from 'vue' | ||
| 75 | +import { useRoute, useRouter } from 'vue-router' | ||
| 76 | + | ||
| 77 | +const $route = useRoute(); | ||
| 78 | +const $router = useRouter(); | ||
| 79 | + | ||
| 80 | +const themeVars = ref({ | ||
| 81 | + swipeIndicatorInactiveBackground: '#fff', | ||
| 82 | +}); | ||
| 83 | + | ||
| 84 | +const images = ref([ | ||
| 85 | + 'https://cdn.ipadbiz.cn/bieyuan/map/swiper_img.png', | ||
| 86 | + 'https://cdn.ipadbiz.cn/bieyuan/map/_DL92427.png', | ||
| 87 | + 'https://cdn.ipadbiz.cn/bieyuan/map/swiper_img.png', | ||
| 88 | + 'https://cdn.ipadbiz.cn/bieyuan/map/swiper_img.png', | ||
| 89 | +]); | ||
| 90 | + | ||
| 91 | +const active = ref(2); | ||
| 92 | +const play_audio_index = ref(null); | ||
| 93 | + | ||
| 94 | +const audioList = ref([{ | ||
| 95 | + text: '5分钟观呼吸', | ||
| 96 | + src: 'https://cdn.ipadbiz.cn/bieyuan/map/1130958712.mp3', | ||
| 97 | + play: false, | ||
| 98 | +}, { | ||
| 99 | + text: '10分钟正念静坐', | ||
| 100 | + src: 'https://cdn.ipadbiz.cn/bieyuan/map/1130958712.mp3', | ||
| 101 | + play: false, | ||
| 102 | +}, { | ||
| 103 | + text: '15分钟正念静坐', | ||
| 104 | + src: 'https://cdn.ipadbiz.cn/bieyuan/map/1130958712.mp3', | ||
| 105 | + play: false, | ||
| 106 | +}]) | ||
| 107 | + | ||
| 108 | +const playAudio = ({src}, index) => { | ||
| 109 | + audio.value.src = src; | ||
| 110 | + play_audio_index.value = index; | ||
| 111 | + let play_status = audio.value.play() // 播放 | ||
| 112 | + if (play_status) { | ||
| 113 | + console.warn('start'); | ||
| 114 | + play_status.then(() => { | ||
| 115 | + console.warn('success'); | ||
| 116 | + }).catch((e) => { | ||
| 117 | + // 失败 | ||
| 118 | + console.log('Operation is too fast, audio play fails') | ||
| 119 | + }) | ||
| 120 | + } | ||
| 121 | +} | ||
| 122 | + | ||
| 123 | +const audio = ref(new Audio()); | ||
| 124 | + | ||
| 125 | +const audio_play = (src, index) => { | ||
| 126 | + audio.value.src = src; | ||
| 127 | +} | ||
| 128 | +</script> | ||
| 129 | + | ||
| 130 | +<style lang="less"> | ||
| 131 | +.info-page { | ||
| 132 | + background-color: #EBEBEB; | ||
| 133 | + height: 100vh; | ||
| 134 | + overflow: scroll; | ||
| 135 | + position: relative; | ||
| 136 | + .info-content-wrapper { | ||
| 137 | + // position: absolute; | ||
| 138 | + // top: 14.9rem; | ||
| 139 | + margin: 1rem; | ||
| 140 | + margin-top: 0; | ||
| 141 | + // padding: 1rem; | ||
| 142 | + border-radius: 0.5rem; | ||
| 143 | + background-color: white; | ||
| 144 | + .info-header { | ||
| 145 | + padding: 1rem 2rem 0; | ||
| 146 | + display: flex; | ||
| 147 | + justify-content: space-between; | ||
| 148 | + // align-items: center; | ||
| 149 | + .info-title { | ||
| 150 | + font-size: 1.25rem; | ||
| 151 | + margin-bottom: 0.25rem; | ||
| 152 | + } | ||
| 153 | + .info-sub-title { | ||
| 154 | + font-size: 0.85rem; | ||
| 155 | + color: #A0A8B1; | ||
| 156 | + } | ||
| 157 | + .info-btn { | ||
| 158 | + width: 3rem; | ||
| 159 | + height: 1.5rem; | ||
| 160 | + border: 1px solid #DD7850; | ||
| 161 | + color: #DD7850; | ||
| 162 | + border-radius: 0.8rem; | ||
| 163 | + font-size: 0.85rem; | ||
| 164 | + text-align: center; | ||
| 165 | + line-height: 1.5rem; | ||
| 166 | + } | ||
| 167 | + } | ||
| 168 | + .info-content { | ||
| 169 | + padding: 1rem; | ||
| 170 | + } | ||
| 171 | + .audio-wrapper { | ||
| 172 | + padding: 1rem 0; | ||
| 173 | + .audio-item { | ||
| 174 | + color: #47525F; | ||
| 175 | + display: flex; | ||
| 176 | + justify-content: space-between; | ||
| 177 | + align-items: center; | ||
| 178 | + padding: 1rem; | ||
| 179 | + background-color: #FFF; | ||
| 180 | + border-radius: 0.25rem; | ||
| 181 | + margin: 1rem; | ||
| 182 | + box-shadow: 0 0 0.5rem rgba(0, 0, 0, 0.1); | ||
| 183 | + &.click { | ||
| 184 | + border: 1px solid #DD7850; | ||
| 185 | + } | ||
| 186 | + .audio-icon { | ||
| 187 | + width: 2rem; | ||
| 188 | + height: 2rem; | ||
| 189 | + background-image: url('https://cdn.ipadbiz.cn/bieyuan/map/icon/audio_icon.png'); /* 使用上传的图标 */ | ||
| 190 | + background-size: cover; | ||
| 191 | + &.click { | ||
| 192 | + animation: pulse 1.5s infinite; | ||
| 193 | + } | ||
| 194 | + } | ||
| 195 | + | ||
| 196 | + @keyframes pulse { | ||
| 197 | + 0% { | ||
| 198 | + transform: scale(1); | ||
| 199 | + } | ||
| 200 | + 50% { | ||
| 201 | + transform: scale(1.2); | ||
| 202 | + } | ||
| 203 | + 100% { | ||
| 204 | + transform: scale(1); | ||
| 205 | + } | ||
| 206 | + } | ||
| 207 | + } | ||
| 208 | + } | ||
| 209 | + } | ||
| 210 | +} | ||
| 211 | +</style> |
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date: 2023-05-19 14:54:27 | 2 | * @Date: 2023-05-19 14:54:27 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2024-09-15 19:04:38 | 4 | + * @LastEditTime: 2024-09-18 09:49:17 |
| 5 | * @FilePath: /map-demo/src/views/bieyuan/map.vue | 5 | * @FilePath: /map-demo/src/views/bieyuan/map.vue |
| 6 | * @Description: 公众地图主体页面 | 6 | * @Description: 公众地图主体页面 |
| 7 | --> | 7 | --> |
| ... | @@ -16,6 +16,12 @@ | ... | @@ -16,6 +16,12 @@ |
| 16 | src="https://cdn.ipadbiz.cn/bieyuan/map/icon/scan@3x.png" | 16 | src="https://cdn.ipadbiz.cn/bieyuan/map/icon/scan@3x.png" |
| 17 | /> | 17 | /> |
| 18 | </div> | 18 | </div> |
| 19 | + | ||
| 20 | + <van-config-provider :theme-vars="themeVars"> | ||
| 21 | + <van-floating-panel v-model:height="info_height" :anchors="anchors" @height-change="onHeightChange"> | ||
| 22 | + <page-info></page-info> | ||
| 23 | + </van-floating-panel> | ||
| 24 | + </van-config-provider> | ||
| 19 | </div> | 25 | </div> |
| 20 | </template> | 26 | </template> |
| 21 | 27 | ||
| ... | @@ -28,6 +34,7 @@ import $ from 'jquery'; | ... | @@ -28,6 +34,7 @@ import $ from 'jquery'; |
| 28 | import { useRect } from '@vant/use'; | 34 | import { useRect } from '@vant/use'; |
| 29 | import { mapAPI } from '@/api/map.js' | 35 | import { mapAPI } from '@/api/map.js' |
| 30 | import wx from 'weixin-js-sdk' | 36 | import wx from 'weixin-js-sdk' |
| 37 | +import pageInfo from '@/views/bieyuan/info.vue' | ||
| 31 | 38 | ||
| 32 | const GPS = { | 39 | const GPS = { |
| 33 | PI: 3.14159265358979324, | 40 | PI: 3.14159265358979324, |
| ... | @@ -86,7 +93,7 @@ const GPS = { | ... | @@ -86,7 +93,7 @@ const GPS = { |
| 86 | }; | 93 | }; |
| 87 | 94 | ||
| 88 | export default { | 95 | export default { |
| 89 | - components: { }, | 96 | + components: { pageInfo }, |
| 90 | data() { | 97 | data() { |
| 91 | return { | 98 | return { |
| 92 | map: '', | 99 | map: '', |
| ... | @@ -108,6 +115,11 @@ export default { | ... | @@ -108,6 +115,11 @@ export default { |
| 108 | data_rotation: 0, // 接口获取-地图旋转角度 | 115 | data_rotation: 0, // 接口获取-地图旋转角度 |
| 109 | data_paths: {}, // 接口获取-地图导航路径 | 116 | data_paths: {}, // 接口获取-地图导航路径 |
| 110 | data_path_list: [], // 接口获取-地图导航路径 | 117 | data_path_list: [], // 接口获取-地图导航路径 |
| 118 | + info_height: 0, | ||
| 119 | + anchors: [0, Math.round(0.4 * window.innerHeight), Math.round(1 * window.innerHeight)], | ||
| 120 | + themeVars: { | ||
| 121 | + floatingPanelHeaderHeight: 0, | ||
| 122 | + } | ||
| 111 | } | 123 | } |
| 112 | }, | 124 | }, |
| 113 | async mounted() { | 125 | async mounted() { |
| ... | @@ -149,6 +161,10 @@ export default { | ... | @@ -149,6 +161,10 @@ export default { |
| 149 | }); | 161 | }); |
| 150 | // 设置贴片地图 | 162 | // 设置贴片地图 |
| 151 | this.setTitleLayer(); | 163 | this.setTitleLayer(); |
| 164 | + // | ||
| 165 | + setTimeout(() => { | ||
| 166 | + this.info_height = Math.round(0.4 * window.innerHeight); | ||
| 167 | + }, 2000); | ||
| 152 | }, | 168 | }, |
| 153 | watch: { | 169 | watch: { |
| 154 | }, | 170 | }, |
| ... | @@ -517,6 +533,9 @@ export default { | ... | @@ -517,6 +533,9 @@ export default { |
| 517 | // path: '/bieyuan/scan' | 533 | // path: '/bieyuan/scan' |
| 518 | // }) | 534 | // }) |
| 519 | }, | 535 | }, |
| 536 | + onHeightChange ({ height }) { | ||
| 537 | + console.warn('拖动完成', height); | ||
| 538 | + } | ||
| 520 | } | 539 | } |
| 521 | } | 540 | } |
| 522 | </script> | 541 | </script> | ... | ... |
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date: 2024-09-15 11:45:13 | 2 | * @Date: 2024-09-15 11:45:13 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2024-09-15 18:54:36 | 4 | + * @LastEditTime: 2024-09-18 11:15:56 |
| 5 | * @FilePath: /map-demo/src/views/bieyuan/scan.vue | 5 | * @FilePath: /map-demo/src/views/bieyuan/scan.vue |
| 6 | * @Description: 文件描述 | 6 | * @Description: 文件描述 |
| 7 | --> | 7 | --> | ... | ... |
| ... | @@ -118,10 +118,10 @@ export default ({ command, mode }) => { | ... | @@ -118,10 +118,10 @@ export default ({ command, mode }) => { |
| 118 | host: '0.0.0.0', | 118 | host: '0.0.0.0', |
| 119 | port: viteEnv.VITE_PORT, // 本地服务端口 | 119 | port: viteEnv.VITE_PORT, // 本地服务端口 |
| 120 | // strictPort: true, // 设为true时若端口已被占用则会直接退出, 而不是尝试下一个可用端口 | 120 | // strictPort: true, // 设为true时若端口已被占用则会直接退出, 而不是尝试下一个可用端口 |
| 121 | - https: { | 121 | + // https: { |
| 122 | - key: fs.readFileSync(path.resolve(__dirname, 'keys/localhost+2-key.pem')), | 122 | + // key: fs.readFileSync(path.resolve(__dirname, 'keys/localhost+2-key.pem')), |
| 123 | - cert: fs.readFileSync(path.resolve(__dirname, 'keys/localhost+2.pem')), | 123 | + // cert: fs.readFileSync(path.resolve(__dirname, 'keys/localhost+2.pem')), |
| 124 | - }, | 124 | + // }, |
| 125 | // open: false, // 在服务器启动时自动在浏览器中打开应用程序. 当此值为字符串时, 会被当作URL的路径名. | 125 | // open: false, // 在服务器启动时自动在浏览器中打开应用程序. 当此值为字符串时, 会被当作URL的路径名. |
| 126 | // proxy: { // 代理 | 126 | // proxy: { // 代理 |
| 127 | // '/srv/': { | 127 | // '/srv/': { | ... | ... |
-
Please register or login to post a comment