mirror of
https://github.com/pixelfed/pixelfed.git
synced 2024-11-22 14:31:26 +00:00
Add Archive Posts
This commit is contained in:
parent
6e45021fc2
commit
e9ef0c887a
7 changed files with 346 additions and 80 deletions
|
@ -15,7 +15,8 @@ use App\{
|
||||||
Media,
|
Media,
|
||||||
Notification,
|
Notification,
|
||||||
Profile,
|
Profile,
|
||||||
Status
|
Status,
|
||||||
|
StatusArchived
|
||||||
};
|
};
|
||||||
use App\Transformer\Api\{
|
use App\Transformer\Api\{
|
||||||
AccountTransformer,
|
AccountTransformer,
|
||||||
|
@ -39,6 +40,7 @@ use App\Jobs\VideoPipeline\{
|
||||||
use App\Services\NotificationService;
|
use App\Services\NotificationService;
|
||||||
use App\Services\MediaPathService;
|
use App\Services\MediaPathService;
|
||||||
use App\Services\MediaBlocklistService;
|
use App\Services\MediaBlocklistService;
|
||||||
|
use App\Services\StatusService;
|
||||||
|
|
||||||
class BaseApiController extends Controller
|
class BaseApiController extends Controller
|
||||||
{
|
{
|
||||||
|
@ -286,4 +288,75 @@ class BaseApiController extends Controller
|
||||||
|
|
||||||
return response()->json($res, 200, [], JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
|
return response()->json($res, 200, [], JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function archive(Request $request, $id)
|
||||||
|
{
|
||||||
|
abort_if(!$request->user(), 403);
|
||||||
|
|
||||||
|
$status = Status::whereNull('in_reply_to_id')
|
||||||
|
->whereNull('reblog_of_id')
|
||||||
|
->whereProfileId($request->user()->profile_id)
|
||||||
|
->findOrFail($id);
|
||||||
|
|
||||||
|
if($status->scope === 'archived') {
|
||||||
|
return [200];
|
||||||
|
}
|
||||||
|
|
||||||
|
$archive = new StatusArchived;
|
||||||
|
$archive->status_id = $status->id;
|
||||||
|
$archive->profile_id = $status->profile_id;
|
||||||
|
$archive->original_scope = $status->scope;
|
||||||
|
$archive->save();
|
||||||
|
|
||||||
|
$status->scope = 'archived';
|
||||||
|
$status->visibility = 'draft';
|
||||||
|
$status->save();
|
||||||
|
|
||||||
|
StatusService::del($status->id);
|
||||||
|
|
||||||
|
// invalidate caches
|
||||||
|
|
||||||
|
return [200];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function unarchive(Request $request, $id)
|
||||||
|
{
|
||||||
|
abort_if(!$request->user(), 403);
|
||||||
|
|
||||||
|
$status = Status::whereNull('in_reply_to_id')
|
||||||
|
->whereNull('reblog_of_id')
|
||||||
|
->whereProfileId($request->user()->profile_id)
|
||||||
|
->findOrFail($id);
|
||||||
|
|
||||||
|
if($status->scope !== 'archived') {
|
||||||
|
return [200];
|
||||||
|
}
|
||||||
|
|
||||||
|
$archive = StatusArchived::whereStatusId($status->id)
|
||||||
|
->whereProfileId($status->profile_id)
|
||||||
|
->firstOrFail();
|
||||||
|
|
||||||
|
$status->scope = $archive->original_scope;
|
||||||
|
$status->visibility = $archive->original_scope;
|
||||||
|
$status->save();
|
||||||
|
|
||||||
|
$archive->delete();
|
||||||
|
|
||||||
|
return [200];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function archivedPosts(Request $request)
|
||||||
|
{
|
||||||
|
abort_if(!$request->user(), 403);
|
||||||
|
|
||||||
|
$statuses = Status::whereProfileId($request->user()->profile_id)
|
||||||
|
->whereScope('archived')
|
||||||
|
->orderByDesc('id')
|
||||||
|
->simplePaginate(10);
|
||||||
|
|
||||||
|
$fractal = new Fractal\Manager();
|
||||||
|
$fractal->setSerializer(new ArraySerializer());
|
||||||
|
$resource = new Fractal\Resource\Collection($statuses, new StatusStatelessTransformer());
|
||||||
|
return $fractal->createData($resource)->toArray();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -616,6 +616,8 @@
|
||||||
<div v-if="status && user.id != status.account.id && !relationship.blocking && !user.is_admin" class="list-group-item rounded cursor-pointer text-danger" @click="blockProfile()">Block</div>
|
<div v-if="status && user.id != status.account.id && !relationship.blocking && !user.is_admin" class="list-group-item rounded cursor-pointer text-danger" @click="blockProfile()">Block</div>
|
||||||
<div v-if="status && user.id != status.account.id && relationship.blocking && !user.is_admin" class="list-group-item rounded cursor-pointer text-danger" @click="unblockProfile()">Unblock</div>
|
<div v-if="status && user.id != status.account.id && relationship.blocking && !user.is_admin" class="list-group-item rounded cursor-pointer text-danger" @click="unblockProfile()">Unblock</div>
|
||||||
<a v-if="user && user.id != status.account.id && !user.is_admin" class="list-group-item rounded cursor-pointer text-danger text-decoration-none" :href="reportUrl()">Report</a>
|
<a v-if="user && user.id != status.account.id && !user.is_admin" class="list-group-item rounded cursor-pointer text-danger text-decoration-none" :href="reportUrl()">Report</a>
|
||||||
|
<div v-if="status && user.id == status.account.id && status.visibility != 'archived'" class="list-group-item rounded cursor-pointer text-danger" @click="archivePost(status)">Archive</div>
|
||||||
|
<div v-if="status && user.id == status.account.id && status.visibility == 'archived'" class="list-group-item rounded cursor-pointer text-danger" @click="unarchivePost(status)">Unarchive</div>
|
||||||
<div v-if="status && (user.is_admin || user.id == status.account.id)" class="list-group-item rounded cursor-pointer text-danger" @click="deletePost(ctxMenuStatus)">Delete</div>
|
<div v-if="status && (user.is_admin || user.id == status.account.id)" class="list-group-item rounded cursor-pointer text-danger" @click="deletePost(ctxMenuStatus)">Delete</div>
|
||||||
<div class="list-group-item rounded cursor-pointer text-lighter" @click="closeCtxMenu()">Cancel</div>
|
<div class="list-group-item rounded cursor-pointer text-lighter" @click="closeCtxMenu()">Cancel</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1757,6 +1759,29 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
archivePost(status) {
|
||||||
|
if(window.confirm('Are you sure you want to archive this post?') == false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
axios.post('/api/pixelfed/v2/status/' + status.id + '/archive')
|
||||||
|
.then(res => {
|
||||||
|
this.$refs.ctxModal.hide();
|
||||||
|
window.location.href = '/';
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
unarchivePost(status) {
|
||||||
|
if(window.confirm('Are you sure you want to unarchive this post?') == false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
axios.post('/api/pixelfed/v2/status/' + status.id + '/unarchive')
|
||||||
|
.then(res => {
|
||||||
|
this.$refs.ctxModal.hide();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -181,64 +181,68 @@
|
||||||
<li v-if="owner" class="nav-item border-top">
|
<li v-if="owner" class="nav-item border-top">
|
||||||
<a :class="this.mode == 'bookmarks' ? 'nav-link text-dark' : 'nav-link'" href="#" v-on:click.prevent="switchMode('bookmarks')"><i class="fas fa-bookmark"></i> <span class="d-none d-md-inline-block small pl-1">SAVED</span></a>
|
<a :class="this.mode == 'bookmarks' ? 'nav-link text-dark' : 'nav-link'" href="#" v-on:click.prevent="switchMode('bookmarks')"><i class="fas fa-bookmark"></i> <span class="d-none d-md-inline-block small pl-1">SAVED</span></a>
|
||||||
</li>
|
</li>
|
||||||
|
<li v-if="owner" class="nav-item border-top">
|
||||||
|
<a :class="this.mode == 'archives' ? 'nav-link text-dark' : 'nav-link'" href="#" v-on:click.prevent="switchMode('archives')"><i class="far fa-folder-open"></i> <span class="d-none d-md-inline-block small pl-1">ARCHIVES</span></a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="container px-0">
|
<div class="container px-0">
|
||||||
<div class="profile-timeline mt-md-4">
|
<div class="profile-timeline mt-md-4">
|
||||||
<div class="row" v-if="mode == 'grid'">
|
<div v-if="mode == 'grid'">
|
||||||
<div class="col-4 p-1 p-md-3" v-for="(s, index) in timeline" :key="'tlob:'+index">
|
<div class="row">
|
||||||
<a class="card info-overlay card-md-border-0" :href="statusUrl(s)" v-once>
|
<div class="col-4 p-1 p-md-3" v-for="(s, index) in timeline" :key="'tlob:'+index">
|
||||||
<div class="square">
|
<a class="card info-overlay card-md-border-0" :href="statusUrl(s)" v-once>
|
||||||
<div v-if="s.sensitive" class="square-content">
|
<div class="square">
|
||||||
<div class="info-overlay-text-label">
|
<div v-if="s.sensitive" class="square-content">
|
||||||
|
<div class="info-overlay-text-label">
|
||||||
|
<h5 class="text-white m-auto font-weight-bold">
|
||||||
|
<span>
|
||||||
|
<span class="far fa-eye-slash fa-lg p-2 d-flex-inline"></span>
|
||||||
|
</span>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<blur-hash-canvas
|
||||||
|
width="32"
|
||||||
|
height="32"
|
||||||
|
:hash="s.media_attachments[0].blurhash"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else class="square-content">
|
||||||
|
<blur-hash-image
|
||||||
|
width="32"
|
||||||
|
height="32"
|
||||||
|
:hash="s.media_attachments[0].blurhash"
|
||||||
|
:src="s.media_attachments[0].preview_url"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<span v-if="s.pf_type == 'photo:album'" class="float-right mr-3 post-icon"><i class="fas fa-images fa-2x"></i></span>
|
||||||
|
<span v-if="s.pf_type == 'video'" class="float-right mr-3 post-icon"><i class="fas fa-video fa-2x"></i></span>
|
||||||
|
<span v-if="s.pf_type == 'video:album'" class="float-right mr-3 post-icon"><i class="fas fa-film fa-2x"></i></span>
|
||||||
|
<div class="info-overlay-text">
|
||||||
<h5 class="text-white m-auto font-weight-bold">
|
<h5 class="text-white m-auto font-weight-bold">
|
||||||
<span>
|
<span>
|
||||||
<span class="far fa-eye-slash fa-lg p-2 d-flex-inline"></span>
|
<span class="far fa-comment fa-lg p-2 d-flex-inline"></span>
|
||||||
|
<span class="d-flex-inline">{{formatCount(s.reply_count)}}</span>
|
||||||
</span>
|
</span>
|
||||||
</h5>
|
</h5>
|
||||||
</div>
|
</div>
|
||||||
<blur-hash-canvas
|
|
||||||
width="32"
|
|
||||||
height="32"
|
|
||||||
:hash="s.media_attachments[0].blurhash"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div v-else class="square-content">
|
|
||||||
|
|
||||||
<blur-hash-image
|
|
||||||
width="32"
|
|
||||||
height="32"
|
|
||||||
:hash="s.media_attachments[0].blurhash"
|
|
||||||
:src="s.media_attachments[0].preview_url"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<span v-if="s.pf_type == 'photo:album'" class="float-right mr-3 post-icon"><i class="fas fa-images fa-2x"></i></span>
|
|
||||||
<span v-if="s.pf_type == 'video'" class="float-right mr-3 post-icon"><i class="fas fa-video fa-2x"></i></span>
|
|
||||||
<span v-if="s.pf_type == 'video:album'" class="float-right mr-3 post-icon"><i class="fas fa-film fa-2x"></i></span>
|
|
||||||
<div class="info-overlay-text">
|
|
||||||
<h5 class="text-white m-auto font-weight-bold">
|
|
||||||
<span>
|
|
||||||
<span class="far fa-comment fa-lg p-2 d-flex-inline"></span>
|
|
||||||
<span class="d-flex-inline">{{formatCount(s.reply_count)}}</span>
|
|
||||||
</span>
|
|
||||||
</h5>
|
|
||||||
</div>
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div v-if="timeline.length == 0" class="col-12">
|
||||||
|
<div class="py-5 text-center text-muted">
|
||||||
|
<p><i class="fas fa-camera-retro fa-2x"></i></p>
|
||||||
|
<p class="h2 font-weight-light pt-3">No posts yet</p>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div v-if="timeline.length == 0" class="col-12">
|
|
||||||
<div class="py-5 text-center text-muted">
|
|
||||||
<p><i class="fas fa-camera-retro fa-2x"></i></p>
|
|
||||||
<p class="h2 font-weight-light pt-3">No posts yet</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div v-if="timeline.length">
|
||||||
<div v-if="timeline.length && mode == 'grid'">
|
<infinite-loading @infinite="infiniteTimeline">
|
||||||
<infinite-loading @infinite="infiniteTimeline">
|
<div slot="no-more"></div>
|
||||||
<div slot="no-more"></div>
|
<div slot="no-results"></div>
|
||||||
<div slot="no-results"></div>
|
</infinite-loading>
|
||||||
</infinite-loading>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="mode == 'bookmarks'">
|
<div v-if="mode == 'bookmarks'">
|
||||||
<div v-if="bookmarksLoading">
|
<div v-if="bookmarksLoading">
|
||||||
|
@ -280,8 +284,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="mode == 'collections'">
|
<div v-if="mode == 'collections'">
|
||||||
<div v-if="collections.length" class="row">
|
<div v-if="collections.length && collectionsLoaded" class="row">
|
||||||
<div class="col-4 p-1 p-sm-2 p-md-3" v-for="(c, index) in collections">
|
<div class="col-4 p-1 p-sm-2 p-md-3" v-for="(c, index) in collections">
|
||||||
<a class="card info-overlay card-md-border-0" :href="c.url">
|
<a class="card info-overlay card-md-border-0" :href="c.url">
|
||||||
<div class="square">
|
<div class="square">
|
||||||
|
@ -298,6 +303,28 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div v-if="mode == 'archives'">
|
||||||
|
<div v-if="archives.length" class="col-12 col-md-8 offset-md-2 px-0 mb-sm-3 timeline mt-5">
|
||||||
|
<div class="alert alert-info">
|
||||||
|
<p class="mb-0">Posts you archive can only be seen by you.</p>
|
||||||
|
<p class="mb-0">For more information see the <a href="/site/kb/sharing-media">Sharing Media</a> help center page.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-for="(status, index) in archives">
|
||||||
|
<status-card
|
||||||
|
:class="{ 'border-top': index === 0 }"
|
||||||
|
:status="status"
|
||||||
|
:reaction-bar="false"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<infinite-loading @infinite="archivesInfiniteLoader">
|
||||||
|
<div slot="no-more"></div>
|
||||||
|
<div slot="no-results"></div>
|
||||||
|
</infinite-loading>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -663,6 +690,7 @@
|
||||||
</style>
|
</style>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
import VueMasonry from 'vue-masonry-css'
|
import VueMasonry from 'vue-masonry-css'
|
||||||
|
import StatusCard from './partials/StatusCard.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: [
|
props: [
|
||||||
|
@ -671,6 +699,11 @@
|
||||||
'profile-settings',
|
'profile-settings',
|
||||||
'profile-username'
|
'profile-username'
|
||||||
],
|
],
|
||||||
|
|
||||||
|
components: {
|
||||||
|
StatusCard,
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
ids: [],
|
ids: [],
|
||||||
|
@ -684,7 +717,7 @@
|
||||||
owner: false,
|
owner: false,
|
||||||
layout: this.profileLayout,
|
layout: this.profileLayout,
|
||||||
mode: 'grid',
|
mode: 'grid',
|
||||||
modes: ['grid', 'collections', 'bookmarks'],
|
modes: ['grid', 'collections', 'bookmarks', 'archives'],
|
||||||
modalStatus: false,
|
modalStatus: false,
|
||||||
relationship: {},
|
relationship: {},
|
||||||
followers: [],
|
followers: [],
|
||||||
|
@ -700,6 +733,7 @@
|
||||||
bookmarks: [],
|
bookmarks: [],
|
||||||
bookmarksPage: 2,
|
bookmarksPage: 2,
|
||||||
collections: [],
|
collections: [],
|
||||||
|
collectionsLoaded: false,
|
||||||
collectionsPage: 2,
|
collectionsPage: 2,
|
||||||
isMobile: false,
|
isMobile: false,
|
||||||
ctxEmbedPayload: null,
|
ctxEmbedPayload: null,
|
||||||
|
@ -709,6 +743,8 @@
|
||||||
followingModalSearchCache: null,
|
followingModalSearchCache: null,
|
||||||
followingModalTab: 'following',
|
followingModalTab: 'following',
|
||||||
bookmarksLoading: true,
|
bookmarksLoading: true,
|
||||||
|
archives: [],
|
||||||
|
archivesPage: 2
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
beforeMount() {
|
beforeMount() {
|
||||||
|
@ -734,6 +770,39 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(u.has('m') && this.modes.includes(u.get('m'))) {
|
||||||
|
this.mode = u.get('m');
|
||||||
|
|
||||||
|
if(this.mode == 'bookmarks') {
|
||||||
|
axios.get('/api/local/bookmarks')
|
||||||
|
.then(res => {
|
||||||
|
this.bookmarks = res.data;
|
||||||
|
this.bookmarksLoading = false;
|
||||||
|
}).catch(err => {
|
||||||
|
this.mode = 'grid';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.mode == 'collections') {
|
||||||
|
axios.get('/api/local/profile/collections/' + this.profileId)
|
||||||
|
.then(res => {
|
||||||
|
this.collections = res.data
|
||||||
|
this.collectionsLoaded = true;
|
||||||
|
}).catch(err => {
|
||||||
|
this.mode = 'grid';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.mode == 'archives') {
|
||||||
|
axios.get('/api/pixelfed/v2/statuses/archives')
|
||||||
|
.then(res => {
|
||||||
|
this.archives = res.data;
|
||||||
|
}).catch(err => {
|
||||||
|
this.mode = 'grid';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
|
@ -858,19 +927,15 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
switchMode(mode) {
|
switchMode(mode) {
|
||||||
this.mode = _.indexOf(this.modes, mode) ? mode : 'grid';
|
if(mode == 'grid') {
|
||||||
if(this.mode == 'bookmarks' && this.bookmarks.length == 0) {
|
this.mode = mode;
|
||||||
axios.get('/api/local/bookmarks')
|
} else if(mode == 'bookmarks' && this.bookmarks.length) {
|
||||||
.then(res => {
|
this.mode = 'bookmarks';
|
||||||
this.bookmarks = res.data;
|
} else if(mode == 'collections' && this.collections.length) {
|
||||||
this.bookmarksLoading = false;
|
this.mode = 'collections';
|
||||||
});
|
} else {
|
||||||
}
|
window.location.href = '/' + this.profileUsername + '?m=' + mode;
|
||||||
if(this.mode == 'collections' && this.collections.length == 0) {
|
return;
|
||||||
axios.get('/api/local/profile/collections/' + this.profileId)
|
|
||||||
.then(res => {
|
|
||||||
this.collections = res.data
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1362,6 +1427,23 @@
|
||||||
joinedAtFormat(created) {
|
joinedAtFormat(created) {
|
||||||
let d = new Date(created);
|
let d = new Date(created);
|
||||||
return d.toDateString();
|
return d.toDateString();
|
||||||
|
},
|
||||||
|
|
||||||
|
archivesInfiniteLoader($state) {
|
||||||
|
axios.get('/api/pixelfed/v2/statuses/archives', {
|
||||||
|
params: {
|
||||||
|
page: this.archivesPage
|
||||||
|
}
|
||||||
|
}).then(res => {
|
||||||
|
if(res.data.length) {
|
||||||
|
this.archives.push(...res.data);
|
||||||
|
this.archivesPage++;
|
||||||
|
$state.loaded();
|
||||||
|
} else {
|
||||||
|
$state.complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,14 +11,16 @@
|
||||||
<div class="list-group text-center">
|
<div class="list-group text-center">
|
||||||
<!-- <div v-if="status && status.account.id != profile.id && ctxMenuRelationship && ctxMenuRelationship.following" class="list-group-item rounded cursor-pointer font-weight-bold text-danger" @click="ctxMenuUnfollow()">Unfollow</div>
|
<!-- <div v-if="status && status.account.id != profile.id && ctxMenuRelationship && ctxMenuRelationship.following" class="list-group-item rounded cursor-pointer font-weight-bold text-danger" @click="ctxMenuUnfollow()">Unfollow</div>
|
||||||
<div v-if="status && status.account.id != profile.id && ctxMenuRelationship && !ctxMenuRelationship.following" class="list-group-item rounded cursor-pointer font-weight-bold text-primary" @click="ctxMenuFollow()">Follow</div> -->
|
<div v-if="status && status.account.id != profile.id && ctxMenuRelationship && !ctxMenuRelationship.following" class="list-group-item rounded cursor-pointer font-weight-bold text-primary" @click="ctxMenuFollow()">Follow</div> -->
|
||||||
<div class="list-group-item rounded cursor-pointer" @click="ctxMenuGoToPost()">View Post</div>
|
<div v-if="status.visibility !== 'archived'" class="list-group-item rounded cursor-pointer" @click="ctxMenuGoToPost()">View Post</div>
|
||||||
<div class="list-group-item rounded cursor-pointer" @click="ctxMenuGoToProfile()">View Profile</div>
|
<div v-if="status.visibility !== 'archived'" class="list-group-item rounded cursor-pointer" @click="ctxMenuGoToProfile()">View Profile</div>
|
||||||
<!-- <div v-if="status && status.local == true && !status.in_reply_to_id" class="list-group-item rounded cursor-pointer" @click="ctxMenuEmbed()">Embed</div>
|
<!-- <div v-if="status && status.local == true && !status.in_reply_to_id" class="list-group-item rounded cursor-pointer" @click="ctxMenuEmbed()">Embed</div>
|
||||||
<div class="list-group-item rounded cursor-pointer" @click="ctxMenuCopyLink()">Copy Link</div> -->
|
<div class="list-group-item rounded cursor-pointer" @click="ctxMenuCopyLink()">Copy Link</div> -->
|
||||||
<div class="list-group-item rounded cursor-pointer" @click="ctxMenuShare()">Share</div>
|
<div v-if="status.visibility !== 'archived'" class="list-group-item rounded cursor-pointer" @click="ctxMenuShare()">Share</div>
|
||||||
<div v-if="status && profile && profile.is_admin == true" class="list-group-item rounded cursor-pointer" @click="ctxModMenuShow()">Moderation Tools</div>
|
<div v-if="status && profile && profile.is_admin == true && status.visibility !== 'archived'" class="list-group-item rounded cursor-pointer" @click="ctxModMenuShow()">Moderation Tools</div>
|
||||||
<div v-if="status && status.account.id != profile.id" class="list-group-item rounded cursor-pointer text-danger" @click="ctxMenuReportPost()">Report</div>
|
<div v-if="status && status.account.id != profile.id" class="list-group-item rounded cursor-pointer text-danger" @click="ctxMenuReportPost()">Report</div>
|
||||||
<div v-if="status && (profile.is_admin || profile.id == status.account.id)" class="list-group-item rounded cursor-pointer text-danger" @click="deletePost(status)">Delete</div>
|
<div v-if="status && profile.id == status.account.id && status.visibility !== 'archived'" class="list-group-item rounded cursor-pointer text-danger" @click="archivePost(status)">Archive</div>
|
||||||
|
<div v-if="status && profile.id == status.account.id && status.visibility == 'archived'" class="list-group-item rounded cursor-pointer text-danger" @click="unarchivePost(status)">Unarchive</div>
|
||||||
|
<div v-if="status && (profile.is_admin || profile.id == status.account.id) && status.visibility !== 'archived'" class="list-group-item rounded cursor-pointer text-danger" @click="deletePost(status)">Delete</div>
|
||||||
<div class="list-group-item rounded cursor-pointer text-lighter" @click="closeCtxMenu()">Cancel</div>
|
<div class="list-group-item rounded cursor-pointer text-lighter" @click="closeCtxMenu()">Cancel</div>
|
||||||
</div>
|
</div>
|
||||||
</b-modal>
|
</b-modal>
|
||||||
|
@ -680,6 +682,29 @@
|
||||||
ownerOrAdmin(status) {
|
ownerOrAdmin(status) {
|
||||||
return this.owner(status) || this.admin();
|
return this.owner(status) || this.admin();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
archivePost(status) {
|
||||||
|
if(window.confirm('Are you sure you want to archive this post?') == false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
axios.post('/api/pixelfed/v2/status/' + status.id + '/archive')
|
||||||
|
.then(res => {
|
||||||
|
this.$emit('status-delete', status.id);
|
||||||
|
this.closeModals();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
unarchivePost(status) {
|
||||||
|
if(window.confirm('Are you sure you want to unarchive this post?') == false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
axios.post('/api/pixelfed/v2/status/' + status.id + '/unarchive')
|
||||||
|
.then(res => {
|
||||||
|
this.closeModals();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -77,7 +77,10 @@
|
||||||
<div class="postPresenterContainer" style="background: #000;">
|
<div class="postPresenterContainer" style="background: #000;">
|
||||||
|
|
||||||
<div v-if="status.pf_type === 'photo'" class="w-100">
|
<div v-if="status.pf_type === 'photo'" class="w-100">
|
||||||
<photo-presenter :status="status" v-on:lightbox="lightbox" v-on:togglecw="status.sensitive = false"></photo-presenter>
|
<photo-presenter
|
||||||
|
:status="status"
|
||||||
|
v-on:lightbox="lightbox"
|
||||||
|
v-on:togglecw="status.sensitive = false"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-else-if="status.pf_type === 'video'" class="w-100">
|
<div v-else-if="status.pf_type === 'video'" class="w-100">
|
||||||
|
@ -149,9 +152,13 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="timestamp mt-2">
|
<div class="timestamp mt-2">
|
||||||
<p class="small mb-0">
|
<p class="small mb-0">
|
||||||
<a :href="statusUrl(status)" class="text-muted text-uppercase">
|
<a v-if="status.visibility != 'archived'" :href="statusUrl(status)" class="text-muted text-uppercase">
|
||||||
<timeago :datetime="status.created_at" :auto-update="60" :converter-options="{includeSeconds:true}" :title="timestampFormat(status.created_at)" v-b-tooltip.hover.bottom></timeago>
|
<timeago :datetime="status.created_at" :auto-update="60" :converter-options="{includeSeconds:true}" :title="timestampFormat(status.created_at)" v-b-tooltip.hover.bottom></timeago>
|
||||||
</a>
|
</a>
|
||||||
|
<span v-else class="text-muted text-uppercase">
|
||||||
|
Posted <timeago :datetime="status.created_at" :auto-update="60" :converter-options="{includeSeconds:true}" :title="timestampFormat(status.created_at)" v-b-tooltip.hover.bottom></timeago>
|
||||||
|
</span>
|
||||||
|
|
||||||
<span v-if="recommended">
|
<span v-if="recommended">
|
||||||
<span class="px-1">·</span>
|
<span class="px-1">·</span>
|
||||||
<span class="text-muted">Based on popular and trending content</span>
|
<span class="text-muted">Based on popular and trending content</span>
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<a class="text-dark font-weight-bold" data-toggle="collapse" href="#collapse2" role="button" aria-expanded="false" aria-controls="collapse2">
|
<a class="text-dark font-weight-bold" data-toggle="collapse" href="#collapse2" role="button" aria-expanded="false" aria-controls="collapse2">
|
||||||
<i class="fas fa-chevron-down mr-2"></i>
|
<i class="fas fa-chevron-down mr-2"></i>
|
||||||
How do I share a post with multiple photos or videos?
|
How do I share a post with multiple photos or videos?
|
||||||
|
@ -43,7 +43,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<a class="text-dark font-weight-bold" data-toggle="collapse" href="#collapse3" role="button" aria-expanded="false" aria-controls="collapse3">
|
<a class="text-dark font-weight-bold" data-toggle="collapse" href="#collapse3" role="button" aria-expanded="false" aria-controls="collapse3">
|
||||||
<i class="fas fa-chevron-down mr-2"></i>
|
<i class="fas fa-chevron-down mr-2"></i>
|
||||||
How do I add a caption before sharing my photos or videos on Pixelfed?
|
How do I add a caption before sharing my photos or videos on Pixelfed?
|
||||||
|
@ -54,7 +54,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<a class="text-dark font-weight-bold" data-toggle="collapse" href="#collapse4" role="button" aria-expanded="false" aria-controls="collapse4">
|
<a class="text-dark font-weight-bold" data-toggle="collapse" href="#collapse4" role="button" aria-expanded="false" aria-controls="collapse4">
|
||||||
<i class="fas fa-chevron-down mr-2"></i>
|
<i class="fas fa-chevron-down mr-2"></i>
|
||||||
How do I add a filter to my photos?
|
How do I add a filter to my photos?
|
||||||
|
@ -74,7 +74,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<a class="text-dark font-weight-bold" data-toggle="collapse" href="#collapse5" role="button" aria-expanded="false" aria-controls="collapse5">
|
<a class="text-dark font-weight-bold" data-toggle="collapse" href="#collapse5" role="button" aria-expanded="false" aria-controls="collapse5">
|
||||||
<i class="fas fa-chevron-down mr-2"></i>
|
<i class="fas fa-chevron-down mr-2"></i>
|
||||||
How do I add a description to each photo or video for the visually impaired?
|
How do I add a description to each photo or video for the visually impaired?
|
||||||
|
@ -94,8 +94,8 @@
|
||||||
<p class="small text-muted"><i class="fas fa-info-circle mr-1"></i> Image descriptions are federated to instances where supported.</p>
|
<p class="small text-muted"><i class="fas fa-info-circle mr-1"></i> Image descriptions are federated to instances where supported.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<a class="text-dark font-weight-bold" data-toggle="collapse" href="#collapse6" role="button" aria-expanded="false" aria-controls="collapse6">
|
<a class="text-dark font-weight-bold" data-toggle="collapse" href="#collapse6" role="button" aria-expanded="false" aria-controls="collapse6">
|
||||||
<i class="fas fa-chevron-down mr-2"></i>
|
<i class="fas fa-chevron-down mr-2"></i>
|
||||||
What types of photos or videos can I upload?
|
What types of photos or videos can I upload?
|
||||||
|
@ -104,14 +104,14 @@
|
||||||
<div>
|
<div>
|
||||||
You can upload the following media types:
|
You can upload the following media types:
|
||||||
<ul>
|
<ul>
|
||||||
@foreach(explode(',', config('pixelfed.media_types')) as $type)
|
@foreach(explode(',', config_cache('pixelfed.media_types')) as $type)
|
||||||
<li class="font-weight-bold">{{$type}}</li>
|
<li class="font-weight-bold">{{$type}}</li>
|
||||||
@endforeach
|
@endforeach
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</p>
|
</p>
|
||||||
{{-- <p>
|
{{-- <p>
|
||||||
<a class="text-dark font-weight-bold" data-toggle="collapse" href="#collapse7" role="button" aria-expanded="false" aria-controls="collapse7">
|
<a class="text-dark font-weight-bold" data-toggle="collapse" href="#collapse7" role="button" aria-expanded="false" aria-controls="collapse7">
|
||||||
<i class="fas fa-chevron-down mr-2"></i>
|
<i class="fas fa-chevron-down mr-2"></i>
|
||||||
What is the limit for photo and video file sizes?
|
What is the limit for photo and video file sizes?
|
||||||
|
@ -122,7 +122,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</p> --}}
|
</p> --}}
|
||||||
{{-- <p>
|
{{-- <p>
|
||||||
<a class="text-dark font-weight-bold" data-toggle="collapse" href="#collapse8" role="button" aria-expanded="false" aria-controls="collapse8">
|
<a class="text-dark font-weight-bold" data-toggle="collapse" href="#collapse8" role="button" aria-expanded="false" aria-controls="collapse8">
|
||||||
<i class="fas fa-chevron-down mr-2"></i>
|
<i class="fas fa-chevron-down mr-2"></i>
|
||||||
When I share a photo, what's the image resolution?
|
When I share a photo, what's the image resolution?
|
||||||
|
@ -133,7 +133,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</p> --}}
|
</p> --}}
|
||||||
{{-- <p>
|
{{-- <p>
|
||||||
<a class="text-dark font-weight-bold" data-toggle="collapse" href="#collapse9" role="button" aria-expanded="false" aria-controls="collapse9">
|
<a class="text-dark font-weight-bold" data-toggle="collapse" href="#collapse9" role="button" aria-expanded="false" aria-controls="collapse9">
|
||||||
<i class="fas fa-chevron-down mr-2"></i>
|
<i class="fas fa-chevron-down mr-2"></i>
|
||||||
Can I edit my post captions, photos or videos after sharing them?
|
Can I edit my post captions, photos or videos after sharing them?
|
||||||
|
@ -144,7 +144,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</p> --}}
|
</p> --}}
|
||||||
<p>
|
<p>
|
||||||
<a class="text-dark font-weight-bold" data-toggle="collapse" href="#collapse10" role="button" aria-expanded="false" aria-controls="collapse10">
|
<a class="text-dark font-weight-bold" data-toggle="collapse" href="#collapse10" role="button" aria-expanded="false" aria-controls="collapse10">
|
||||||
<i class="fas fa-chevron-down mr-2"></i>
|
<i class="fas fa-chevron-down mr-2"></i>
|
||||||
How can I disable comments/replies on my post?
|
How can I disable comments/replies on my post?
|
||||||
|
@ -159,7 +159,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<a class="text-dark font-weight-bold" data-toggle="collapse" href="#collapse11" role="button" aria-expanded="false" aria-controls="collapse11">
|
<a class="text-dark font-weight-bold" data-toggle="collapse" href="#collapse11" role="button" aria-expanded="false" aria-controls="collapse11">
|
||||||
<i class="fas fa-chevron-down mr-2"></i>
|
<i class="fas fa-chevron-down mr-2"></i>
|
||||||
How many people can I tag or mention in my comments or posts?
|
How many people can I tag or mention in my comments or posts?
|
||||||
|
@ -171,4 +171,55 @@
|
||||||
</div>
|
</div>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@endsection
|
<p>
|
||||||
|
<a class="text-dark font-weight-bold" data-toggle="collapse" href="#collapse12" role="button" aria-expanded="false" aria-controls="collapse11">
|
||||||
|
<i class="fas fa-chevron-down mr-2"></i>
|
||||||
|
What does archive mean?
|
||||||
|
</a>
|
||||||
|
<div class="collapse" id="collapse12">
|
||||||
|
<div>
|
||||||
|
You can archive your posts which prevents anyone from interacting or viewing it.
|
||||||
|
<br />
|
||||||
|
<strong class="text-danger">Archived posts cannot be deleted or otherwise interacted with. You may not recieve interactions (comments, likes, shares) from other servers while a post is archived.</strong>
|
||||||
|
<br />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<a class="text-dark font-weight-bold" data-toggle="collapse" href="#collapse13" role="button" aria-expanded="false" aria-controls="collapse11">
|
||||||
|
<i class="fas fa-chevron-down mr-2"></i>
|
||||||
|
How can I archive my posts?
|
||||||
|
</a>
|
||||||
|
<div class="collapse" id="collapse13">
|
||||||
|
<div>
|
||||||
|
To archive your posts:
|
||||||
|
<ul>
|
||||||
|
<li>Navigate to the post</li>
|
||||||
|
<li>Open the menu, click the <i class="fas fa-ellipsis-v text-muted mx-2 cursor-pointer"></i> or <i class="fas fa-ellipsis-h text-muted mx-2 cursor-pointer"></i> button</li>
|
||||||
|
<li>Click on <span class="small font-weight-bold cursor-pointer">Archive</span></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<a class="text-dark font-weight-bold" data-toggle="collapse" href="#collapse14" role="button" aria-expanded="false" aria-controls="collapse11">
|
||||||
|
<i class="fas fa-chevron-down mr-2"></i>
|
||||||
|
How do I unarchive my posts?
|
||||||
|
</a>
|
||||||
|
<div class="collapse" id="collapse14">
|
||||||
|
<div>
|
||||||
|
To unarchive your posts:
|
||||||
|
<ul>
|
||||||
|
<li>Navigate to your profile</li>
|
||||||
|
<li>Click on the <strong>ARCHIVES</strong> tab</li>
|
||||||
|
<li>Scroll to the post you want to unarchive</li>
|
||||||
|
<li>Open the menu, click the <i class="fas fa-ellipsis-v text-muted mx-2 cursor-pointer"></i> or <i class="fas fa-ellipsis-h text-muted mx-2 cursor-pointer"></i> button</li>
|
||||||
|
<li>Click on <span class="small font-weight-bold cursor-pointer">Unarchive</span></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
@endsection
|
||||||
|
|
|
@ -200,6 +200,9 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact
|
||||||
Route::get('discover/posts/places', 'DiscoverController@trendingPlaces');
|
Route::get('discover/posts/places', 'DiscoverController@trendingPlaces');
|
||||||
Route::get('seasonal/yir', 'SeasonalController@getData');
|
Route::get('seasonal/yir', 'SeasonalController@getData');
|
||||||
Route::post('seasonal/yir', 'SeasonalController@store');
|
Route::post('seasonal/yir', 'SeasonalController@store');
|
||||||
|
Route::post('status/{id}/archive', 'ApiController@archive');
|
||||||
|
Route::post('status/{id}/unarchive', 'ApiController@unarchive');
|
||||||
|
Route::get('statuses/archives', 'ApiController@archivedPosts');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue