소스 검색

Update ComposeModal.vue, fix redirect after posting. Fixes #3254

Daniel Supernault 3 년 전
부모
커밋
5db64e94a3
1개의 변경된 파일174개의 추가작업 그리고 56개의 파일을 삭제
  1. 174 56
      resources/assets/js/components/ComposeModal.vue

+ 174 - 56
resources/assets/js/components/ComposeModal.vue

@@ -1,6 +1,6 @@
 <template>
 <template>
-<div>
-	<input type="file" id="pf-dz" name="media" class="w-100 h-100 d-none file-input" v-bind:accept="config.uploader.media_types">
+<div class="compose-modal-component">
+	<input type="file" id="pf-dz" name="media" class="w-100 h-100 d-none file-input" multiple="" v-bind:accept="config.uploader.media_types">
 	<canvas class="d-none" id="pr_canvas"></canvas>
 	<canvas class="d-none" id="pr_canvas"></canvas>
 	<img class="d-none" id="pr_img">
 	<img class="d-none" id="pr_img">
 	<div class="timeline">
 	<div class="timeline">
@@ -446,9 +446,20 @@
 						<div class="border-bottom">
 						<div class="border-bottom">
 							<p class="px-4 mb-0 py-2 cursor-pointer" @click="showTagCard()">Tag people</p>
 							<p class="px-4 mb-0 py-2 cursor-pointer" @click="showTagCard()">Tag people</p>
 						</div>
 						</div>
+						<div class="border-bottom">
+							<p class="px-4 mb-0 py-2 cursor-pointer" @click="showCollectionCard()">
+								<span>Add to Collection <span class="ml-2 badge badge-primary">NEW</span></span>
+								<span class="float-right">
+									<span v-if="collectionsSelected.length" href="#" class="btn btn-outline-secondary btn-sm small mr-3 mt-n1 disabled" style="font-size:10px;padding:3px 5px;text-transform: uppercase" disabled>
+										{{collectionsSelected.length}}
+									</span>
+									<span class="text-decoration-none"><i class="fas fa-chevron-right fa-lg text-lighter"></i></span>
+								</span>
+							</p>
+						</div>
 						<div class="border-bottom">
 						<div class="border-bottom">
 							<p class="px-4 mb-0 py-2 cursor-pointer" @click="showLicenseCard()">
 							<p class="px-4 mb-0 py-2 cursor-pointer" @click="showLicenseCard()">
-								<span>Add license <span class="ml-2 badge badge-primary">NEW</span></span>
+								<span>Add license</span>
 								<span class="float-right">
 								<span class="float-right">
 									<a v-if="licenseTitle" href="#" @click.prevent="showLicenseCard()" class="btn btn-outline-secondary btn-sm small mr-3 mt-n1 disabled" style="font-size:10px;padding:3px;text-transform: uppercase" disabled>{{licenseTitle}}</a>
 									<a v-if="licenseTitle" href="#" @click.prevent="showLicenseCard()" class="btn btn-outline-secondary btn-sm small mr-3 mt-n1 disabled" style="font-size:10px;padding:3px;text-transform: uppercase" disabled>{{licenseTitle}}</a>
 									<a href="#" @click.prevent="showLicenseCard()" class="text-decoration-none"><i class="fas fa-chevron-right fa-lg text-lighter"></i></a>
 									<a href="#" @click.prevent="showLicenseCard()" class="text-decoration-none"><i class="fas fa-chevron-right fa-lg text-lighter"></i></a>
@@ -660,19 +671,30 @@
 					</div>
 					</div>
 
 
 					<div v-if="page == 'addToCollection'" class="w-100 h-100 p-3">
 					<div v-if="page == 'addToCollection'" class="w-100 h-100 p-3">
-						<div class="list-group mb-3">
-							<div class="list-group-item cursor-pointer compose-action border" @click="goBack()">
+						<div v-if="collectionsLoaded && collections.length" class="list-group mb-3 collections-list-group">
+							<div
+								v-for="(collection, index) in collections"
+								class="list-group-item cursor-pointer compose-action border"
+								:class="{ active: collectionsSelected.includes(index) }"
+								@click="toggleCollectionItem(index)">
 								<div class="media">
 								<div class="media">
-								  <img src="" class="mr-3" alt="" width="50px" height="50px">
+								  <img :src="collection.thumb" class="mr-3" alt="" width="50px" height="50px">
 								  <div class="media-body">
 								  <div class="media-body">
-								    <h5 class="mt-0">collection title</h5>
-								    <p class="mb-0 text-muted small">3 Photos - Created 2h ago</p>
+								    <h5 class="mt-0">{{ collection.title }}</h5>
+								    <p class="mb-0 text-muted small">{{ collection.post_count }} Posts - Created {{ timeAgo(collection.published_at) }} ago</p>
 								  </div>
 								  </div>
 								</div>
 								</div>
 							</div>
 							</div>
+
+							<button
+								v-if="collectionsCanLoadMore"
+								class="btn btn-light btn-block font-weight-bold mt-3"
+								@click="loadMoreCollections">
+								Load more
+							</button>
 						</div>
 						</div>
 						<p class="d-flex justify-content-between mb-0">
 						<p class="d-flex justify-content-between mb-0">
-							<button type="button" @click="goBack()" class="btn btn-link text-muted font-weight-bold text-decoration-none">Cancel</button>
+							<button type="button" @click="clearSelectedCollections()" class="btn btn-link text-muted font-weight-bold text-decoration-none">Clear</button>
 							<button type="button" @click="goBack()" class="btn btn-primary font-weight-bold">Save</button>
 							<button type="button" @click="goBack()" class="btn btn-primary font-weight-bold">Save</button>
 						</p>
 						</p>
 					</div>
 					</div>
@@ -812,47 +834,6 @@
 </div>
 </div>
 </template>
 </template>
 
 
-<style type="text/css" scoped>
-	.media-drawer-filters {
-		overflow-x: scroll;
-		flex-wrap:unset;
-	}
-	.media-drawer-filters::-webkit-scrollbar {
-		width: 0px;
-		background: transparent;
-	}
-	.media-drawer-filters .nav-link {
-		min-width:100px;
-		padding-top: 1rem;
-		padding-bottom: 1rem;
-	}
-	.media-drawer-filters .active {
-		color: #fff;
-		font-weight: bold;
-	}
-    @media (hover: none) and (pointer: coarse) {
-	    .media-drawer-filters::-webkit-scrollbar {
-	        display: none;
-	    }
-    }
-    .no-focus {
-		border-color: none;
-		outline: 0;
-		box-shadow: none;
-    }
-	a.list-group-item {
-		text-decoration: none;
-	}
-	a.list-group-item:hover {
-		text-decoration: none;
-		background-color: #f8f9fa !important;
-	}
-	.compose-action:hover {
-		cursor: pointer;
-		background-color: #f8f9fa !important;
-	}
-</style>
-
 <script type="text/javascript">
 <script type="text/javascript">
 import VueCropper from 'vue-cropperjs';
 import VueCropper from 'vue-cropperjs';
 import 'cropperjs/dist/cropper.css';
 import 'cropperjs/dist/cropper.css';
@@ -1021,7 +1002,12 @@ export default {
 			pollOptionModel: null,
 			pollOptionModel: null,
 			pollOptions: [],
 			pollOptions: [],
 			pollExpiry: 1440,
 			pollExpiry: 1440,
-			postingPoll: false
+			postingPoll: false,
+			collections: [],
+			collectionsSelected: [],
+			collectionsLoaded: false,
+			collectionsPage: 1,
+			collectionsCanLoadMore: false,
 		}
 		}
 	},
 	},
 
 
@@ -1048,6 +1034,10 @@ export default {
 	},
 	},
 
 
 	methods: {
 	methods: {
+		timeAgo(ts) {
+			return App.util.format.timeAgo(ts);
+		},
+
 		fetchProfile() {
 		fetchProfile() {
 			let tags = {
 			let tags = {
 				public: 'Public',
 				public: 'Public',
@@ -1246,6 +1236,7 @@ export default {
 					if(this.composeText == 'Add optional caption...') {
 					if(this.composeText == 'Add optional caption...') {
 						this.composeText = '';
 						this.composeText = '';
 					}
 					}
+
 					let data = {
 					let data = {
 						media: this.media,
 						media: this.media,
 						caption: this.composeText,
 						caption: this.composeText,
@@ -1258,17 +1249,28 @@ export default {
 						license: this.licenseId,
 						license: this.licenseId,
 						video: this.video
 						video: this.video
 					};
 					};
+
+					if(this.collectionsSelected.length) {
+						data.collections = this.collectionsSelected
+							.map(idx => {
+								return this.collections[idx].id;
+						});
+					}
+
 					axios.post('/api/compose/v0/publish', data)
 					axios.post('/api/compose/v0/publish', data)
 					.then(res => {
 					.then(res => {
-						let data = res.data;
-						if(location.pathname === '/i/web/compose') {
-							location.href = '/i/web/post/' + data.split('/').at(-1);
+						if(location.pathname === '/i/web/compose' && res.data && res.data.length) {
+							location.href = '/i/web/post/' + res.data.split('/').slice(-1)[0];
 						} else {
 						} else {
 							location.href = data;
 							location.href = data;
 						}
 						}
 					}).catch(err => {
 					}).catch(err => {
-						let msg = err.response.data.message ? err.response.data.message : 'An unexpected error occured.'
-						swal('Oops, something went wrong!', msg, 'error');
+						if(err.response) {
+							let msg = err.response.data.message ? err.response.data.message : 'An unexpected error occured.'
+							swal('Oops, something went wrong!', msg, 'error');
+						} else {
+							swal('Oops, something went wrong!', err.message, 'error');
+						}
 					});
 					});
 					return;
 					return;
 				break;
 				break;
@@ -1774,7 +1776,123 @@ export default {
 
 
 		filesize(val) {
 		filesize(val) {
 			return filesize(val * 1024, {round: 0});
 			return filesize(val * 1024, {round: 0});
+		},
+
+		showCollectionCard() {
+			this.pageTitle = 'Add to Collection(s)';
+			this.page = 'addToCollection';
+
+			if(!this.collectionsLoaded) {
+				this.fetchCollections();
+			}
+		},
+
+		fetchCollections() {
+			axios.get(`/api/local/profile/collections/${this.profile.id}`)
+			.then(res => {
+				this.collections = res.data;
+				this.collectionsLoaded = true;
+				this.collectionsCanLoadMore = res.data.length == 9;
+				this.collectionsPage++;
+			});
+		},
+
+		toggleCollectionItem(index) {
+			if(!this.collectionsSelected.includes(index)) {
+				if(this.collectionsSelected.length == 7) {
+					swal('Oops!', 'You can only share to 5 collections.', 'info');
+					return;
+				}
+				this.collectionsSelected.push(index);
+			} else {
+				this.collectionsSelected = this.collectionsSelected.filter(c => c != index);
+			}
+		},
+
+		clearSelectedCollections() {
+			this.collectionsSelected = [];
+			this.pageTitle = 'Compose';
+			this.page = 3;
+		},
+
+		loadMoreCollections() {
+			this.collectionsCanLoadMore = false;
+
+			axios.get(`/api/local/profile/collections/${this.profile.id}`, {
+				params: {
+					page: this.collectionsPage
+				}
+			})
+			.then(res => {
+				let ids = this.collections.map(c => c.id);
+				let data = res.data.filter(res => {
+					return !ids.includes(res.id);
+				});
+
+				if(!data || !data.length) {
+					return;
+				}
+
+				this.collections.push(...data);
+				this.collectionsPage++;
+				this.collectionsCanLoadMore = true;
+			});
 		}
 		}
 	}
 	}
 }
 }
 </script>
 </script>
+
+<style lang="scss">
+	.compose-modal-component {
+		.media-drawer-filters {
+			overflow-x: scroll;
+			flex-wrap:unset;
+		}
+		.media-drawer-filters::-webkit-scrollbar {
+			width: 0px;
+			background: transparent;
+		}
+		.media-drawer-filters .nav-link {
+			min-width:100px;
+			padding-top: 1rem;
+			padding-bottom: 1rem;
+		}
+		.media-drawer-filters .active {
+			color: #fff;
+			font-weight: bold;
+		}
+		@media (hover: none) and (pointer: coarse) {
+			.media-drawer-filters::-webkit-scrollbar {
+				display: none;
+			}
+		}
+		.no-focus {
+			border-color: none;
+			outline: 0;
+			box-shadow: none;
+		}
+		a.list-group-item {
+			text-decoration: none;
+		}
+		a.list-group-item:hover {
+			text-decoration: none;
+			background-color: #f8f9fa !important;
+		}
+		.compose-action:hover {
+			cursor: pointer;
+			background-color: #f8f9fa !important;
+		}
+		.collections-list-group {
+			max-height: 500px;
+			overflow-y: auto;
+
+			.list-group-item {
+				&.active {
+					color: #212529;
+					border-color: #60a5fa !important;
+					background-color: #dbeafe !important;
+				}
+			}
+		}
+	}
+</style>