mirror of
https://github.com/pixelfed/pixelfed.git
synced 2024-12-23 13:33:18 +00:00
commit
28e8bfedf7
5 changed files with 142 additions and 7 deletions
|
@ -205,4 +205,36 @@ class CollectionController extends Controller
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function deleteId(Request $request)
|
||||||
|
{
|
||||||
|
$this->validate($request, [
|
||||||
|
'collection_id' => 'required|int|min:1|exists:collections,id',
|
||||||
|
'post_id' => 'required|int|min:1|exists:statuses,id'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$profileId = Auth::user()->profile_id;
|
||||||
|
$collectionId = $request->input('collection_id');
|
||||||
|
$postId = $request->input('post_id');
|
||||||
|
|
||||||
|
$collection = Collection::whereProfileId($profileId)->findOrFail($collectionId);
|
||||||
|
$count = $collection->items()->count();
|
||||||
|
|
||||||
|
if($count == 1) {
|
||||||
|
abort(400, 'You cannot delete the only post of a collection!');
|
||||||
|
}
|
||||||
|
|
||||||
|
$status = Status::whereScope('public')
|
||||||
|
->whereIn('type', ['photo', 'photo:album', 'video'])
|
||||||
|
->findOrFail($postId);
|
||||||
|
|
||||||
|
$item = CollectionItem::whereCollectionId($collection->id)
|
||||||
|
->whereObjectType('App\Status')
|
||||||
|
->whereObjectId($status->id)
|
||||||
|
->firstOrFail();
|
||||||
|
|
||||||
|
$item->delete();
|
||||||
|
|
||||||
|
return 200;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
BIN
public/js/collections.js
vendored
BIN
public/js/collections.js
vendored
Binary file not shown.
Binary file not shown.
|
@ -15,7 +15,7 @@
|
||||||
</p>
|
</p>
|
||||||
<p v-if="owner == true" class="pt-3 text-center">
|
<p v-if="owner == true" class="pt-3 text-center">
|
||||||
<span>
|
<span>
|
||||||
<button class="btn btn-outline-light btn-sm" @click.prevent="addToCollection">
|
<button class="btn btn-outline-light btn-sm" @click.prevent="addToCollection" onclick="this.blur();">
|
||||||
<span v-if="loadingPostList == false">Add Photo</span>
|
<span v-if="loadingPostList == false">Add Photo</span>
|
||||||
<span v-else class="px-4">
|
<span v-else class="px-4">
|
||||||
<div class="spinner-border spinner-border-sm" role="status">
|
<div class="spinner-border spinner-border-sm" role="status">
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button class="btn btn-outline-light btn-sm" @click.prevent="editCollection">Edit</button>
|
<button class="btn btn-outline-light btn-sm" @click.prevent="editCollection" onclick="this.blur();">Edit</button>
|
||||||
|
|
||||||
<button class="btn btn-outline-light btn-sm" @click.prevent="deleteCollection">Delete</button>
|
<button class="btn btn-outline-light btn-sm" @click.prevent="deleteCollection">Delete</button>
|
||||||
</span>
|
</span>
|
||||||
|
@ -66,14 +66,17 @@
|
||||||
<option value="private">Followers Only</option>
|
<option value="private">Followers Only</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<button type="button" class="btn btn-primary btn-sm py-1 font-weight-bold px-3 float-right" @click.prevent="updateCollection">Save</button>
|
<div class="d-flex justify-content-between align-items-center pt-3">
|
||||||
|
<a class="text-primary font-weight-bold text-decoration-none" href="#" @click.prevent="showEditPhotosModal">Edit Photos</a>
|
||||||
|
<button type="button" class="btn btn-primary btn-sm py-1 font-weight-bold px-3 float-right" @click.prevent="updateCollection">Save</button>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</b-modal>
|
</b-modal>
|
||||||
<b-modal ref="addPhotoModal" id="add-photo-modal" hide-footer centered title="Add Photo" body-class="m-3">
|
<b-modal ref="addPhotoModal" id="add-photo-modal" hide-footer centered title="Add Photo" body-class="m-3">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="title" class="font-weight-bold text-muted">Add Recent Post</label>
|
<label for="title" class="font-weight-bold text-muted">Add Recent Post</label>
|
||||||
<div class="row m-1" v-if="postsList.length > 0">
|
<div class="row m-1" v-if="postsList.length > 0">
|
||||||
<div v-for="(p, index) in postsList" :key="'postList-'+index" class="col-4 p-1 cursor-pointer">
|
<div v-for="(p, index) in postsList" :key="'postList-'+index" class="col-4 p-1 cursor-pointer" @click="addRecentId(p)">
|
||||||
<div class="square">
|
<div class="square">
|
||||||
<div class="square-content" v-bind:style="'background-image: url(' + p.media_attachments[0].url + ');'"></div>
|
<div class="square-content" v-bind:style="'background-image: url(' + p.media_attachments[0].url + ');'"></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -89,9 +92,34 @@
|
||||||
<input type="text" class="form-control" placeholder="https://pixelfed.dev/p/admin/1" v-model="photoId">
|
<input type="text" class="form-control" placeholder="https://pixelfed.dev/p/admin/1" v-model="photoId">
|
||||||
<p class="help-text small text-muted">Only local, public posts can be added</p>
|
<p class="help-text small text-muted">Only local, public posts can be added</p>
|
||||||
</div>
|
</div>
|
||||||
<button type="button" class="btn btn-primary btn-sm py-1 font-weight-bold px-3 float-right" @click.prevent="pushId">Add Photo</button>
|
<button type="button" class="btn btn-primary btn-sm py-1 font-weight-bold px-3 float-right" @click.prevent="pushId">
|
||||||
|
<span v-if="addingPostToCollection" class="px-4">
|
||||||
|
<div class="spinner-border spinner-border-sm" role="status">
|
||||||
|
<span class="sr-only">Loading...</span>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
<span v-else>
|
||||||
|
Add Photo
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</b-modal>
|
</b-modal>
|
||||||
|
<b-modal ref="editPhotosModal" id="edit-photos-modal" hide-footer centered title="Edit Collection Photos" body-class="m-3">
|
||||||
|
<div class="form-group">
|
||||||
|
<p class="font-weight-bold text-dark text-center">Select a Photo to Delete</p>
|
||||||
|
<div class="row m-1 scrollbar-hidden" v-if="posts.length > 0" style="max-height: 350px;overflow-y: auto;">
|
||||||
|
<div v-for="(p, index) in posts" :key="'plm-'+index" class="col-4 p-1 cursor-pointer">
|
||||||
|
<div :class="[markedForDeletion.indexOf(p.id) == -1 ? 'square' : 'square delete-border']" @click="markPhotoForDeletion(p.id)">
|
||||||
|
<div class="square-content" v-bind:style="'background-image: url(' + p.media_attachments[0].url + ');'"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-show="markedForDeletion.length > 0">
|
||||||
|
<button type="button" @click.prevent="confirmDeletion" class="btn btn-primary font-weight-bold py-0 btn-block mb-0 mt-4">Delete {{markedForDeletion.length}} {{markedForDeletion.length == 1 ? 'photo':'photos'}}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</b-modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -105,6 +133,16 @@
|
||||||
background: rgba(0,0,0,.68);
|
background: rgba(0,0,0,.68);
|
||||||
z-index: 300;
|
z-index: 300;
|
||||||
}
|
}
|
||||||
|
.scrollbar-hidden::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.delete-border {
|
||||||
|
border: 4px solid #ff0000;
|
||||||
|
}
|
||||||
|
.delete-border .square-content {
|
||||||
|
background-color: red;
|
||||||
|
background-blend-mode: screen;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
@ -133,7 +171,9 @@ export default {
|
||||||
visibility: this.collectionVisibility,
|
visibility: this.collectionVisibility,
|
||||||
photoId: '',
|
photoId: '',
|
||||||
postsList: [],
|
postsList: [],
|
||||||
loadingPostList: false
|
loadingPostList: false,
|
||||||
|
addingPostToCollection: false,
|
||||||
|
markedForDeletion: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -202,6 +242,7 @@ export default {
|
||||||
|
|
||||||
pushId() {
|
pushId() {
|
||||||
let max = 18;
|
let max = 18;
|
||||||
|
let addingPostToCollection = true;
|
||||||
let self = this;
|
let self = this;
|
||||||
if(this.posts.length >= max) {
|
if(this.posts.length >= max) {
|
||||||
swal('Error', 'You can only add ' + max + ' posts per collection', 'error');
|
swal('Error', 'You can only add ' + max + ' posts per collection', 'error');
|
||||||
|
@ -228,6 +269,8 @@ export default {
|
||||||
swal('Invalid URL', 'The post you entered was invalid', 'error');
|
swal('Invalid URL', 'The post you entered was invalid', 'error');
|
||||||
this.photoId = '';
|
this.photoId = '';
|
||||||
});
|
});
|
||||||
|
self.$refs.addPhotoModal.hide();
|
||||||
|
window.location.reload();
|
||||||
},
|
},
|
||||||
|
|
||||||
editCollection() {
|
editCollection() {
|
||||||
|
@ -259,6 +302,65 @@ export default {
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
console.log(res.data);
|
console.log(res.data);
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
showEditPhotosModal() {
|
||||||
|
this.$refs.editModal.hide();
|
||||||
|
this.$refs.editPhotosModal.show();
|
||||||
|
},
|
||||||
|
|
||||||
|
markPhotoForDeletion(id) {
|
||||||
|
this.markedForDeletion.indexOf(id) == -1 ?
|
||||||
|
this.markedForDeletion.push(id) :
|
||||||
|
this.markedForDeletion = this.markedForDeletion.filter(d => {
|
||||||
|
return d != id;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
confirmDeletion() {
|
||||||
|
let self = this;
|
||||||
|
let confirmed = window.confirm('Are you sure you want to delete this?');
|
||||||
|
if(confirmed) {
|
||||||
|
this.markedForDeletion.forEach(mfd => {
|
||||||
|
axios.delete('/api/local/collection/item', {
|
||||||
|
params: {
|
||||||
|
collection_id: self.collectionId,
|
||||||
|
post_id: mfd
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(res => {
|
||||||
|
self.removeItem(mfd);
|
||||||
|
this.$refs.editPhotosModal.hide();
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
swal(
|
||||||
|
'Oops!',
|
||||||
|
'An error occured with your request, please try again later.',
|
||||||
|
'error'
|
||||||
|
);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
this.markedForDeletion = [];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
removeItem(id) {
|
||||||
|
this.posts = this.posts.filter(post => {
|
||||||
|
return post.id != id;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
addRecentId(post) {
|
||||||
|
let self = this;
|
||||||
|
axios.post('/api/local/collection/item', {
|
||||||
|
collection_id: self.collectionId,
|
||||||
|
post_id: post.id
|
||||||
|
}).then(res => {
|
||||||
|
window.location.reload();
|
||||||
|
}).catch(err => {
|
||||||
|
swal('Oops!', 'An error occured, please try selecting another post.', 'error');
|
||||||
|
this.photoId = '';
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,6 +156,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact
|
||||||
Route::get('bookmarks', 'InternalApiController@bookmarks');
|
Route::get('bookmarks', 'InternalApiController@bookmarks');
|
||||||
Route::get('collection/items/{id}', 'CollectionController@getItems');
|
Route::get('collection/items/{id}', 'CollectionController@getItems');
|
||||||
Route::post('collection/item', 'CollectionController@storeId');
|
Route::post('collection/item', 'CollectionController@storeId');
|
||||||
|
Route::delete('collection/item', 'CollectionController@deleteId');
|
||||||
Route::get('collection/{id}', 'CollectionController@get');
|
Route::get('collection/{id}', 'CollectionController@get');
|
||||||
Route::post('collection/{id}', 'CollectionController@store');
|
Route::post('collection/{id}', 'CollectionController@store');
|
||||||
Route::delete('collection/{id}', 'CollectionController@delete')->middleware('throttle:maxCollectionsPerHour,60')->middleware('throttle:maxCollectionsPerDay,1440')->middleware('throttle:maxCollectionsPerMonth,43800');
|
Route::delete('collection/{id}', 'CollectionController@delete')->middleware('throttle:maxCollectionsPerHour,60')->middleware('throttle:maxCollectionsPerDay,1440')->middleware('throttle:maxCollectionsPerMonth,43800');
|
||||||
|
|
Loading…
Reference in a new issue