Skip to content

Commit

Permalink
feat(interactables): user picker component (#3506)
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonwoodland authored and JustZacca committed Jun 10, 2022
1 parent 79a3a76 commit 04e8dab
Show file tree
Hide file tree
Showing 14 changed files with 202 additions and 12 deletions.
2 changes: 1 addition & 1 deletion components/interactables/Button/Button.less
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
min-width: 35px;
overflow: hidden;
line-height: unset;
transition: 250ms all ease-in;
transition: all @animation-speed ease-in;

#custom-cursor-area {
display: inline-flex;
Expand Down
1 change: 1 addition & 0 deletions components/interactables/Button/types.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export type ButtonType =
| 'primary'
| 'dark'
| 'link'
| 'info'
| 'success'
Expand Down
4 changes: 4 additions & 0 deletions components/interactables/Checkbox/Checkbox.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<div class="checkbox" :class="{checked: value}">
<check-icon />
<input type="checkbox" :checked="value" @change="$emit('input', $event.target.checked)">
</div>
40 changes: 40 additions & 0 deletions components/interactables/Checkbox/Checkbox.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
.checkbox {
width: 20px;
height: 20px;
display: flex;
justify-content: center;
align-items: center;
border: 2px solid @gray;
border-radius: @corner-rounding;
transition: all @animation-speed ease;

svg, input {
position: absolute;
}

svg {
transition: all @animation-speed ease;
opacity: 0;
transform: scale(0.5);
stroke: @white;
width: 16px;
height: 16px;
}

&.checked {
border-color: @flair-color;
background-color: @flair-color;
&:extend(.glow-flair);

svg {
opacity: 1;
transform: scale(1);
}
}

input {
appearance: none;
width: 24px;
height: 24px;
}
}
21 changes: 21 additions & 0 deletions components/interactables/Checkbox/Checkbox.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<template src="./Checkbox.html"></template>

<script lang="ts">
import Vue from 'vue'
import { CheckIcon } from 'satellite-lucide-icons'
export default Vue.extend({
name: 'Checkbox',
components: {
CheckIcon,
},
props: {
value: {
type: Boolean,
default: false,
},
},
})
</script>

<style scoped lang="less" src="./Checkbox.less"></style>
10 changes: 10 additions & 0 deletions components/interactables/UserPicker/ListItem/ListItem.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<div class="list-item" @click="$emit('click', $event)">
<UiCircle
:type="src ? 'image' : 'random'"
:seed="friend.address"
:size="32"
:source="src"
/>
<div class="name">{{friend.name}}</div>
<InteractablesCheckbox :value="selected"/>
</div>
19 changes: 19 additions & 0 deletions components/interactables/UserPicker/ListItem/ListItem.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
.list-item {
display: flex;
align-items: center;
justify-content: flex-start;
gap: @light-spacing;
cursor: pointer;
padding: @light-spacing;
padding-right: @normal-spacing;

&:hover {
background: @semitransparent-light-gradient;
}

.name {
font-size: @mini-text-size;
flex-grow: 1;

}
}
31 changes: 31 additions & 0 deletions components/interactables/UserPicker/ListItem/ListItem.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<template src="./ListItem.html"></template>

<script lang="ts">
import Vue from 'vue'
import { Friend } from '~/types/ui/friends'
export default Vue.extend({
name: 'ListItem',
props: {
friend: {
type: Object as PropType<Friend>,
required: true,
},
selected: {
type: Boolean,
default: () => false,
},
},
computed: {
src(): string {
const hash =
this.friend?.photoHash ||
this.friend?.profilePicture ||
this.friend?.request?.userInfo?.photoHash
return hash ? `${this.$Config.textile.browser}/ipfs/${hash}` : ''
},
},
})
</script>

<style scoped lang="less" src="./ListItem.less"></style>
16 changes: 16 additions & 0 deletions components/interactables/UserPicker/UserPicker.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<div class="user-picker">
<InteractablesInput
v-model="filter"
size="small"
type="dark"
:placeholder="$t('servers.create.select_friends_placeholder')"
/>
<UiScroll verticalScroll scrollbarVisibility="scroll" enableWrap>
<InteractablesUserPickerListItem
v-for="friend in filteredFriends"
:friend="friend"
:selected="isSelected(friend)"
@click="toggle(friend)"
/>
</UiScroll>
</div>
6 changes: 6 additions & 0 deletions components/interactables/UserPicker/UserPicker.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.user-picker {
height: 200px;
display: flex;
flex-direction: column;
gap: @light-spacing;
}
50 changes: 50 additions & 0 deletions components/interactables/UserPicker/UserPicker.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<template src="./UserPicker.html"></template>

<script lang="ts">
import Vue from 'vue'
import { mapState } from 'vuex'
import { Friend } from '~/types/ui/friends'
import { RootState } from '~/types/store/store'
export default Vue.extend({
name: 'UserPicker',
data: () => ({
selected: [] as Friend[],
filter: '',
}),
computed: {
...mapState({
friends: (state) => (state as RootState).friends.all,
}),
filteredFriends(): Friend[] {
if (!this.filter) {
return this.friends
}
const filterLower = this.filter.toLowerCase()
return this.friends.filter((friend: Friend) => {
return friend.name.toLowerCase().includes(filterLower)
})
},
},
watch: {
selected() {
this.$emit('input', this.selected)
},
},
methods: {
toggle(friend: Friend): void {
if (this.isSelected(friend)) {
const index = this.selected.indexOf(friend)
this.selected.splice(index, 1)
return
}
this.selected.push(friend)
},
isSelected(friend: Friend): boolean {
return this.selected.includes(friend)
},
},
})
</script>

<style scoped lang="less" src="./UserPicker.less"></style>
12 changes: 3 additions & 9 deletions components/views/friends/quick/Quick.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,7 @@
<TypographySubtitle :size="6" :text="$t('pages.chat.new_chat')" />
<TypographyText :text="$t('pages.chat.new_chat_description')" />
</div>
<SettingsPagesUserSearch
v-model="friends"
:placeholder="$t('servers.create.select_friends_placeholder')"
size="small"
type="primary"
drop="bottom"
/>
<InteractablesUserPicker v-model="friends" />
<template v-if="friends.length > 1">
<InteractablesInput
v-model="name"
Expand All @@ -24,11 +18,11 @@
<TypographyError v-if="error" :text="error" small />
</template>
<InteractablesButton
v-if="friends.length"
type="primary"
:type="friends.length ? 'primary' : 'dark'"
size="small"
:text="$t('pages.chat.chat_now')"
:action="confirm"
:loading="isLoading"
full-width
/>
</div>
1 change: 0 additions & 1 deletion components/views/friends/quick/Quick.less
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
left: @sidebar-size + 2rem;
display: flex;
flex-direction: column;
max-height: 24rem;
gap: @normal-spacing;

&.compact {
Expand Down
1 change: 0 additions & 1 deletion components/views/group/icon/GroupIcon.less
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@
}

&.unread {
&:extend(.first-layer);
position: relative;

.label {
Expand Down

0 comments on commit 04e8dab

Please sign in to comment.