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

feat(interactables): user picker component #3506

Merged
merged 10 commits into from
Jun 9, 2022
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">
Copy link
Member

Choose a reason for hiding this comment

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

Captura de ecrã 2022-06-10, às 14 47 05

this is adding a warning when we build locally, could fix you on a separate PR? @jasonwoodland πŸ”¨

Copy link
Member

Choose a reason for hiding this comment

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

added ticket here - AP-1766

<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