Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

チャンネルサイドバー #223

Merged
merged 22 commits into from
Apr 16, 2020
Merged
14 changes: 12 additions & 2 deletions src/assets/mdi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,12 @@ import {
mdiCog,
mdiAccount,
mdiCogs,
mdiBrightness6
mdiBrightness6,
mdiPencilOutline,
mdiToggleSwitchOff,
mdiToggleSwitch,
mdiChevronDoubleLeft,
mdiChevronLeft
} from '@mdi/js'

interface MdiIconsMapping {
Expand Down Expand Up @@ -65,7 +70,12 @@ const mdi: MdiIconsMapping = {
cog: mdiCog,
account: mdiAccount,
cogs: mdiCogs,
'brightness-6': mdiBrightness6
'brightness-6': mdiBrightness6,
pencil: mdiPencilOutline,
'toggle-switch-off': mdiToggleSwitchOff,
'toggle-switch-on': mdiToggleSwitch,
'chevron-double': mdiChevronDoubleLeft,
'chevron-left': mdiChevronLeft
}

export default mdi
135 changes: 135 additions & 0 deletions src/components/Main/MainView/ChannelSideBar/ChannelSideBar.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
<template>
<channel-side-bar-hidden
v-if="!state.isOpen"
@open="toggle"
:viewer-ids="viewerIds"
/>
<channel-side-bar-pinned-list
v-else-if="state.pinnedMode"
@closePinned="togglePinnedMode"
@closeBar="toggle"
:pinned-message="state.pinnedMessage"
/>
<div v-else :style="styles.container" :class="$style.container">
<channel-side-bar-header
:channel-id="channelId"
@close="toggle"
:class="$style.sidebarItem"
/>
<channel-side-bar-viewers
:viewer-ids="viewerIds"
:class="$style.sidebarItem"
/>
<channel-side-bar-topic :class="$style.sidebarItem" />
<channel-side-bar-pinned
:pinned-message-length="state.pinnedMessage.length"
@open="togglePinnedMode"
:class="$style.sidebarItem"
/>
<channel-side-bar-relation
:channel-id="channelId"
:class="$style.sidebarItem"
/>
<channel-side-bar-member
:channel-id="channelId"
:class="$style.sidebarItem"
:viewer-ids="viewerIds"
/>
<channel-side-bar-edit :class="$style.edit" />
</div>
</template>

<script lang="ts">
import {
defineComponent,
computed,
reactive,
PropType
} from '@vue/composition-api'
import { ChannelId } from '@/types/entity-ids'
import store from '@/store'
import { makeStyles } from '@/lib/styles'
import { ChannelViewState } from '@traptitech/traq'
import ChannelSideBarTopic from './ChannelSideBarTopic.vue'
import ChannelSideBarPinned from './ChannelSideBarPinned.vue'
import ChannelSideBarViewers from './ChannelSideBarViewers.vue'
import ChannelSideBarHeader from './ChannelSideBarHeader.vue'
import ChannelSideBarMember from './ChannelSideBarMember.vue'
import ChannelSideBarEdit from './ChannelSideBarEdit.vue'
import ChannelSideBarHidden from './ChannelSideBarHidden.vue'
import ChannelSideBarPinnedList from './ChannelSideBarPinnedList.vue'
import ChannelSideBarRelation from './ChannelSideBarRelation.vue'

const useStyles = () =>
reactive({
container: makeStyles(theme => ({
background: theme.background.secondary,
color: theme.ui.secondary
}))
})

export default defineComponent({
name: 'ChannelSideBar',
components: {
ChannelSideBarTopic,
ChannelSideBarPinned,
ChannelSideBarViewers,
ChannelSideBarHeader,
ChannelSideBarMember,
ChannelSideBarEdit,
ChannelSideBarHidden,
ChannelSideBarPinnedList,
ChannelSideBarRelation
},
props: {
channelId: { type: String as PropType<ChannelId>, requried: true }
},
setup() {
const state = reactive({
isOpen: false,
pinnedMode: false,
pinnedMessage: computed(
() => store.state.domain.messagesView.pinnedMessages
)
})
const styles = useStyles()
const viewerIds = computed(
() => store.getters.domain.messagesView.getCurrentViewersId
)
const toggle = () => {
state.isOpen = !state.isOpen
}
const togglePinnedMode = () => {
state.pinnedMode = !state.pinnedMode
}
return {
state,
toggle,
togglePinnedMode,
viewerIds,
styles
}
}
})
</script>

<style lang="scss" module>
.container {
display: flex;
flex-direction: column;
Comment on lines +118 to +119
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

よく考えたら開いた状態と閉じた状態でメッセージ部分の幅が変わるの微妙だしスクロールバーの位置が微妙だからposition: absoluteでやるべきなきがしてきた
@spa どうしましょう あとで変えるとかにしますか?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

うーん、確かにそんな気もします
とりあえずこれで入れてみて使い勝手的によくなければabsoluteにしますか

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

関係ない人にメンション飛ばしてて草

width: 320px;
height: 100%;
padding: 0 32px;
overflow: auto;
}

.sidebarItem {
margin-top: 16px;
}

.edit {
margin: 24px 0;
flex: 1;
align-items: flex-end;
ryoha000 marked this conversation as resolved.
Show resolved Hide resolved
}
</style>
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<template>
<div :class="$style.container" :style="styles.container">
<div :class="$style.header" @click="onClick">
<h2 :class="$style.headerTitle">{{ title }}</h2>
<slot name="header-control"></slot>
</div>
<slot name="content" />
</div>
</template>

<script lang="ts">
import { defineComponent, computed, reactive } from '@vue/composition-api'
import { makeStyles } from '@/lib/styles'
import store from '@/store'

const useStyles = () =>
reactive({
container: makeStyles(theme => ({
background: theme.background.primary,
color: theme.ui.secondary
}))
})

export default defineComponent({
name: 'ChannelSideBarContent',
props: { title: { type: String, required: true } },
setup(_, context) {
const styles = useStyles()
const onClick = () => {
context.emit('click')
}
return { styles, onClick }
}
})
</script>

<style lang="scss" module>
$headerSize: 1rem;

.container {
display: flex;
flex-direction: column;
width: 256px;
border-radius: 4px;
padding: 12px;
flex-shrink: 0;
}

.header {
display: flex;
justify-content: space-between;
align-items: center;
ryoha000 marked this conversation as resolved.
Show resolved Hide resolved
margin-bottom: 8px;
cursor: pointer;
&:last-child {
margin-bottom: 0;
}
}

.headerTitle {
font-weight: bold;
font-size: $headerSize;
}
</style>
71 changes: 71 additions & 0 deletions src/components/Main/MainView/ChannelSideBar/ChannelSideBarEdit.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<template>
<div :class="$style.container">
<div :class="$style.content" :style="styles.content" @click="onClick">
<Icon
mdi
:name="state.isEditing ? 'toggle-switch-on' : 'toggle-switch-off'"
height="20"
width="20"
/>
<div>編集</div>
</div>
</div>
</template>

<script lang="ts">
import {
defineComponent,
computed,
reactive,
SetupContext
} from '@vue/composition-api'
import { makeStyles } from '@/lib/styles'
import Icon from '@/components/UI/Icon.vue'

type State = {
isEditing: boolean
}

const useStyles = (state: State) =>
reactive({
content: makeStyles(theme => ({
color: state.isEditing ? theme.ui.primary : theme.ui.secondary
}))
})

export default defineComponent({
name: 'ChannelSideBarEdit',
components: { Icon },
setup() {
const state: State = reactive({
isEditing: false
})
const onClick = () => {
state.isEditing = !state.isEditing
}
const styles = useStyles(state)
return { state, styles, onClick }
}
})
</script>

<style lang="scss" module>
$editButtonText: 0.8rem;

.container {
display: flex;
flex-direction: column;
justify-content: flex-end;
}

.content {
bottom: 0;
display: flex;
font-size: $editButtonText;
justify-content: center;
flex-shrink: 0;
cursor: pointer;
user-select: none;
width: 100%;
}
</style>
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<template>
<div :class="$style.container" :style="styles.container">
<channel-side-bar-header-name :channel-name="state.channelName" />
<close-button @click="onClick" :size="28" />
</div>
</template>

<script lang="ts">
import {
defineComponent,
computed,
reactive,
PropType
} from '@vue/composition-api'
import { ChannelId } from '@/types/entity-ids'
import { makeStyles } from '@/lib/styles'
import store from '@/store'
import ChannelSideBarHeaderName from './ChannelSideBarHeaderName.vue'
import CloseButton from '@/components/Main/Modal/SettingModal/CloseButton.vue'

const useStyles = () =>
reactive({
container: makeStyles(theme => ({
color: theme.ui.primary
}))
})

export default defineComponent({
name: 'ChannelSideBarHeader',
props: { channelId: { type: String as PropType<ChannelId>, required: true } },
components: { ChannelSideBarHeaderName, CloseButton },
setup(props, context) {
const state = reactive({
channelName: computed(
() => store.state.entities.channels[props.channelId]?.name
)
})
const onClick = () => {
context.emit('close')
}
const styles = useStyles()
return { state, styles, onClick }
}
})
</script>

<style lang="scss" module>
.container {
display: flex;
justify-content: space-between;
width: 256px;
align-items: center;
flex-shrink: 0;
}
</style>
Loading