diff --git a/package.json b/package.json
index c4dfb7165..032281336 100644
--- a/package.json
+++ b/package.json
@@ -28,6 +28,7 @@
"sass-loader": "^4.0.2",
"vue": "^2.5.13",
"vue-chat-scroll": "^1.2.1",
+ "vue-compose": "^0.7.1",
"vue-i18n": "^7.3.2",
"vue-router": "^3.0.1",
"vue-template-compiler": "^2.3.4",
diff --git a/src/App.scss b/src/App.scss
index 7c6970c12..a0d1a804a 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -628,6 +628,16 @@ nav {
color: $fallback--faint;
color: var(--faint, $fallback--faint);
}
+
+.faint-link {
+ color: $fallback--faint;
+ color: var(--faint, $fallback--faint);
+
+ &:hover {
+ text-decoration: underline;
+ }
+}
+
@media all and (min-width: 800px) {
.logo {
opacity: 1 !important;
@@ -661,6 +671,10 @@ nav {
border-radius: var(--inputRadius, $fallback--inputRadius);
}
+.button-icon {
+ font-size: 1.2em;
+}
+
@keyframes shakeError {
0% {
transform: translateX(0);
@@ -705,16 +719,6 @@ nav {
margin: 0.5em 0 0.5em 0;
}
- .button-icon {
- font-size: 1.2em;
- }
-
- .status .status-actions {
- div {
- max-width: 4em;
- }
- }
-
.menu-button {
display: block;
margin-right: 0.8em;
@@ -723,7 +727,7 @@ nav {
.login-hint {
text-align: center;
-
+
@media all and (min-width: 801px) {
display: none;
}
diff --git a/src/components/attachment/attachment.vue b/src/components/attachment/attachment.vue
index 7e972026e..76affe2db 100644
--- a/src/components/attachment/attachment.vue
+++ b/src/components/attachment/attachment.vue
@@ -88,7 +88,7 @@
.attachment {
position: relative;
- margin: 0.5em 0.5em 0em 0em;
+ margin-top: 0.5em;
align-self: flex-start;
line-height: 0;
diff --git a/src/components/basic_user_card/basic_user_card.js b/src/components/basic_user_card/basic_user_card.js
new file mode 100644
index 000000000..a84414469
--- /dev/null
+++ b/src/components/basic_user_card/basic_user_card.js
@@ -0,0 +1,28 @@
+import UserCardContent from '../user_card_content/user_card_content.vue'
+import UserAvatar from '../user_avatar/user_avatar.vue'
+import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
+
+const BasicUserCard = {
+ props: [
+ 'user'
+ ],
+ data () {
+ return {
+ userExpanded: false
+ }
+ },
+ components: {
+ UserCardContent,
+ UserAvatar
+ },
+ methods: {
+ toggleUserExpanded () {
+ this.userExpanded = !this.userExpanded
+ },
+ userProfileLink (user) {
+ return generateProfileLink(user.id, user.screen_name, this.$store.state.instance.restrictedNicknames)
+ }
+ }
+}
+
+export default BasicUserCard
diff --git a/src/components/basic_user_card/basic_user_card.vue b/src/components/basic_user_card/basic_user_card.vue
new file mode 100644
index 000000000..77fb0aa0f
--- /dev/null
+++ b/src/components/basic_user_card/basic_user_card.vue
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+ {{ user.name }}
+
+
+
+ @{{user.screen_name}}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/block_card/block_card.js b/src/components/block_card/block_card.js
new file mode 100644
index 000000000..11fa27b48
--- /dev/null
+++ b/src/components/block_card/block_card.js
@@ -0,0 +1,37 @@
+import BasicUserCard from '../basic_user_card/basic_user_card.vue'
+
+const BlockCard = {
+ props: ['userId'],
+ data () {
+ return {
+ progress: false
+ }
+ },
+ computed: {
+ user () {
+ return this.$store.getters.userById(this.userId)
+ },
+ blocked () {
+ return this.user.statusnet_blocking
+ }
+ },
+ components: {
+ BasicUserCard
+ },
+ methods: {
+ unblockUser () {
+ this.progress = true
+ this.$store.dispatch('unblockUser', this.user.id).then(() => {
+ this.progress = false
+ })
+ },
+ blockUser () {
+ this.progress = true
+ this.$store.dispatch('blockUser', this.user.id).then(() => {
+ this.progress = false
+ })
+ }
+ }
+}
+
+export default BlockCard
diff --git a/src/components/block_card/block_card.vue b/src/components/block_card/block_card.vue
new file mode 100644
index 000000000..8eb56e250
--- /dev/null
+++ b/src/components/block_card/block_card.vue
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/follow_card/follow_card.js b/src/components/follow_card/follow_card.js
new file mode 100644
index 000000000..425c9c3e8
--- /dev/null
+++ b/src/components/follow_card/follow_card.js
@@ -0,0 +1,45 @@
+import BasicUserCard from '../basic_user_card/basic_user_card.vue'
+import { requestFollow, requestUnfollow } from '../../services/follow_manipulate/follow_manipulate'
+
+const FollowCard = {
+ props: [
+ 'user',
+ 'noFollowsYou'
+ ],
+ data () {
+ return {
+ inProgress: false,
+ requestSent: false,
+ updated: false
+ }
+ },
+ components: {
+ BasicUserCard
+ },
+ computed: {
+ isMe () { return this.$store.state.users.currentUser.id === this.user.id },
+ following () { return this.updated ? this.updated.following : this.user.following },
+ showFollow () {
+ return !this.following || this.updated && !this.updated.following
+ }
+ },
+ methods: {
+ followUser () {
+ this.inProgress = true
+ requestFollow(this.user, this.$store).then(({ sent, updated }) => {
+ this.inProgress = false
+ this.requestSent = sent
+ this.updated = updated
+ })
+ },
+ unfollowUser () {
+ this.inProgress = true
+ requestUnfollow(this.user, this.$store).then(({ updated }) => {
+ this.inProgress = false
+ this.updated = updated
+ })
+ }
+ }
+}
+
+export default FollowCard
diff --git a/src/components/follow_card/follow_card.vue b/src/components/follow_card/follow_card.vue
new file mode 100644
index 000000000..6cb064eb7
--- /dev/null
+++ b/src/components/follow_card/follow_card.vue
@@ -0,0 +1,53 @@
+
+
+
+
+ {{ isMe ? $t('user_card.its_you') : $t('user_card.follows_you') }}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/follow_list/follow_list.js b/src/components/follow_list/follow_list.js
deleted file mode 100644
index 9777c87eb..000000000
--- a/src/components/follow_list/follow_list.js
+++ /dev/null
@@ -1,68 +0,0 @@
-import UserCard from '../user_card/user_card.vue'
-
-const FollowList = {
- data () {
- return {
- loading: false,
- bottomedOut: false,
- error: false
- }
- },
- props: ['userId', 'showFollowers'],
- created () {
- window.addEventListener('scroll', this.scrollLoad)
- if (this.entries.length === 0) {
- this.fetchEntries()
- }
- },
- destroyed () {
- window.removeEventListener('scroll', this.scrollLoad)
- this.$store.dispatch('clearFriendsAndFollowers', this.userId)
- },
- computed: {
- user () {
- return this.$store.getters.userById(this.userId)
- },
- entries () {
- return this.showFollowers ? this.user.followers : this.user.friends
- },
- showFollowsYou () {
- return !this.showFollowers || (this.showFollowers && this.userId !== this.$store.state.users.currentUser.id)
- }
- },
- methods: {
- fetchEntries () {
- if (!this.loading) {
- const command = this.showFollowers ? 'addFollowers' : 'addFriends'
- this.loading = true
- this.$store.dispatch(command, this.userId).then(entries => {
- this.error = false
- this.loading = false
- this.bottomedOut = entries.length === 0
- }).catch(() => {
- this.error = true
- this.loading = false
- })
- }
- },
- scrollLoad (e) {
- const bodyBRect = document.body.getBoundingClientRect()
- const height = Math.max(bodyBRect.height, -(bodyBRect.y))
- if (this.loading === false &&
- this.bottomedOut === false &&
- this.$el.offsetHeight > 0 &&
- (window.innerHeight + window.pageYOffset) >= (height - 750)
- ) {
- this.fetchEntries()
- }
- }
- },
- watch: {
- 'user': 'fetchEntries'
- },
- components: {
- UserCard
- }
-}
-
-export default FollowList
diff --git a/src/components/follow_list/follow_list.vue b/src/components/follow_list/follow_list.vue
deleted file mode 100644
index 27102edf4..000000000
--- a/src/components/follow_list/follow_list.vue
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/src/components/follow_request_card/follow_request_card.js b/src/components/follow_request_card/follow_request_card.js
new file mode 100644
index 000000000..1a00a1c14
--- /dev/null
+++ b/src/components/follow_request_card/follow_request_card.js
@@ -0,0 +1,20 @@
+import BasicUserCard from '../basic_user_card/basic_user_card.vue'
+
+const FollowRequestCard = {
+ props: ['user'],
+ components: {
+ BasicUserCard
+ },
+ methods: {
+ approveUser () {
+ this.$store.state.api.backendInteractor.approveUser(this.user.id)
+ this.$store.dispatch('removeFollowRequest', this.user)
+ },
+ denyUser () {
+ this.$store.state.api.backendInteractor.denyUser(this.user.id)
+ this.$store.dispatch('removeFollowRequest', this.user)
+ }
+ }
+}
+
+export default FollowRequestCard
diff --git a/src/components/follow_request_card/follow_request_card.vue b/src/components/follow_request_card/follow_request_card.vue
new file mode 100644
index 000000000..4a3bbba49
--- /dev/null
+++ b/src/components/follow_request_card/follow_request_card.vue
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/follow_requests/follow_requests.js b/src/components/follow_requests/follow_requests.js
index 11a228aa4..704a76c66 100644
--- a/src/components/follow_requests/follow_requests.js
+++ b/src/components/follow_requests/follow_requests.js
@@ -1,22 +1,13 @@
-import UserCard from '../user_card/user_card.vue'
+import FollowRequestCard from '../follow_request_card/follow_request_card.vue'
const FollowRequests = {
components: {
- UserCard
- },
- created () {
- this.updateRequests()
+ FollowRequestCard
},
computed: {
requests () {
return this.$store.state.api.followRequests
}
- },
- methods: {
- updateRequests () {
- this.$store.state.api.backendInteractor.fetchFollowRequests()
- .then((requests) => { this.$store.commit('setFollowRequests', requests) })
- }
}
}
diff --git a/src/components/follow_requests/follow_requests.vue b/src/components/follow_requests/follow_requests.vue
index 87dc41941..b83c2d68d 100644
--- a/src/components/follow_requests/follow_requests.vue
+++ b/src/components/follow_requests/follow_requests.vue
@@ -4,7 +4,7 @@
{{$t('nav.friend_requests')}}
-
+
diff --git a/src/components/gallery/gallery.vue b/src/components/gallery/gallery.vue
index 3f90caa99..2366ddf7d 100644
--- a/src/components/gallery/gallery.vue
+++ b/src/components/gallery/gallery.vue
@@ -36,6 +36,9 @@
box-sizing: border-box;
// to make failed images a bit more noticeable on chromium
min-width: 2em;
+ &:last-child {
+ margin: 0;
+ }
}
.image-attachment {
diff --git a/src/components/link-preview/link-preview.vue b/src/components/link-preview/link-preview.vue
index e4a247c5f..7394668c4 100644
--- a/src/components/link-preview/link-preview.vue
+++ b/src/components/link-preview/link-preview.vue
@@ -24,10 +24,6 @@
cursor: pointer;
overflow: hidden;
- // TODO: clean up the random margins in attachments, this makes preview line
- // up with attachments...
- margin-right: 0.5em;
-
.card-image {
flex-shrink: 0;
width: 120px;
diff --git a/src/components/mute_card/mute_card.js b/src/components/mute_card/mute_card.js
new file mode 100644
index 000000000..5dd0a9e56
--- /dev/null
+++ b/src/components/mute_card/mute_card.js
@@ -0,0 +1,37 @@
+import BasicUserCard from '../basic_user_card/basic_user_card.vue'
+
+const MuteCard = {
+ props: ['userId'],
+ data () {
+ return {
+ progress: false
+ }
+ },
+ computed: {
+ user () {
+ return this.$store.getters.userById(this.userId)
+ },
+ muted () {
+ return this.user.muted
+ }
+ },
+ components: {
+ BasicUserCard
+ },
+ methods: {
+ unmuteUser () {
+ this.progress = true
+ this.$store.dispatch('unmuteUser', this.user.id).then(() => {
+ this.progress = false
+ })
+ },
+ muteUser () {
+ this.progress = true
+ this.$store.dispatch('muteUser', this.user.id).then(() => {
+ this.progress = false
+ })
+ }
+ }
+}
+
+export default MuteCard
diff --git a/src/components/mute_card/mute_card.vue b/src/components/mute_card/mute_card.vue
new file mode 100644
index 000000000..e1bfe20be
--- /dev/null
+++ b/src/components/mute_card/mute_card.vue
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/components/nav_panel/nav_panel.js b/src/components/nav_panel/nav_panel.js
index ea5d7ea4f..aa3f76053 100644
--- a/src/components/nav_panel/nav_panel.js
+++ b/src/components/nav_panel/nav_panel.js
@@ -1,10 +1,23 @@
+import followRequestFetcher from '../../services/follow_request_fetcher/follow_request_fetcher.service'
+
const NavPanel = {
+ created () {
+ if (this.currentUser && this.currentUser.locked) {
+ const store = this.$store
+ const credentials = store.state.users.currentUser.credentials
+
+ followRequestFetcher.startFetching({ store, credentials })
+ }
+ },
computed: {
currentUser () {
return this.$store.state.users.currentUser
},
chat () {
return this.$store.state.chat.channel
+ },
+ followRequestCount () {
+ return this.$store.state.api.followRequests.length
}
}
}
diff --git a/src/components/nav_panel/nav_panel.vue b/src/components/nav_panel/nav_panel.vue
index 1a269adf9..7a7212fb1 100644
--- a/src/components/nav_panel/nav_panel.vue
+++ b/src/components/nav_panel/nav_panel.vue
@@ -20,8 +20,8 @@
{{ $t("nav.friend_requests")}}
-
- {{currentUser.follow_request_count}}
+
+ {{followRequestCount}}
diff --git a/src/components/registration/registration.vue b/src/components/registration/registration.vue
index f428ead3d..e22b308df 100644
--- a/src/components/registration/registration.vue
+++ b/src/components/registration/registration.vue
@@ -9,7 +9,7 @@