wip bsky client for the web & android
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix(styles): fix outline styles

vi ed8c6a34 f6fb5b6c

+85 -6
+6 -6
src/assets/main.scss
··· 38 38 39 39 -webkit-tap-highlight-color: transparent; 40 40 outline: 2px solid transparent; 41 - outline-offset: 4px; 41 + outline-offset: 2px; 42 42 43 43 transition-property: vars.$transition-properties; 44 44 transition-duration: vars.$transition-duration; 45 45 transition-timing-function: vars.$ease; 46 + } 46 47 47 - &:focus-visible { 48 - outline-color: hsl(var(--blue)); 49 - outline-offset: 2px; 50 - border-radius: 2px; 51 - } 48 + *:focus-visible { 49 + outline-color: hsl(var(--blue)); 50 + border-radius: 2px; 51 + z-index: 5; 52 52 } 53 53 54 54 :root {
+79
src/components/Modals/UserListModal.vue
··· 1 + <script setup lang="ts"> 2 + import { ref, onMounted } from 'vue' 3 + import type { AppBskyActorDefs } from '@atcute/bluesky' 4 + 5 + import Modal from '@/components/UI/BaseModal.vue' 6 + import Button from '@/components/UI/BaseButton.vue' 7 + import ProfileRow from '@/components/Profile/ProfileRow.vue' 8 + import SkeletonLoader from '@/components/UI/SkeletonLoader.vue' 9 + 10 + import { useInfiniteScroll } from '@/composables/useInfiniteScroll' 11 + 12 + const props = defineProps<{ 13 + title: string 14 + users: AppBskyActorDefs.ProfileView[] 15 + loading?: boolean 16 + onReachedBottom?: () => void 17 + hasMore?: boolean 18 + }>() 19 + 20 + const emit = defineEmits<{ 21 + (e: 'close'): void 22 + }>() 23 + 24 + const sentinel = ref<HTMLElement | null>(null) 25 + 26 + const { setup } = useInfiniteScroll(sentinel, () => { 27 + if (props.onReachedBottom && !props.loading) { 28 + props.onReachedBottom() 29 + } 30 + }) 31 + 32 + onMounted(() => { 33 + setup() 34 + }) 35 + </script> 36 + 37 + <template> 38 + <Modal :title="title" width="640px" @close="emit('close')" edge-to-edge> 39 + <div class="user-list" role="list"> 40 + <template v-if="loading && users.length === 0"> 41 + <SkeletonLoader v-for="n in 6" :key="n" /> 42 + </template> 43 + 44 + <ProfileRow v-for="user in users" :key="user.did" :profile="user" @click="emit('close')" /> 45 + 46 + <div ref="sentinel" class="sentinel"></div> 47 + 48 + <div v-if="loading && users.length > 0" class="loading-more"> 49 + <p>loading more...</p> 50 + </div> 51 + <div v-if="!hasMore && users.length > 0" class="loading-more"> 52 + <p>that's all!</p> 53 + </div> 54 + </div> 55 + 56 + <template #footer> 57 + <Button variant="primary" @click="emit('close')">Close</Button> 58 + </template> 59 + </Modal> 60 + </template> 61 + 62 + <style lang="scss" scoped> 63 + .user-list { 64 + display: flex; 65 + flex-direction: column; 66 + max-height: 60vh; 67 + overflow-y: auto; 68 + } 69 + 70 + .sentinel { 71 + height: 1px; 72 + } 73 + 74 + .loading-more { 75 + opacity: 0.6; 76 + text-align: center; 77 + padding: 1rem; 78 + } 79 + </style>