diff --git a/app/Http/Controllers/AdminController.php b/app/Http/Controllers/AdminController.php index 80d096fb9..642e6d220 100644 --- a/app/Http/Controllers/AdminController.php +++ b/app/Http/Controllers/AdminController.php @@ -9,6 +9,7 @@ use App\{ Instance, Media, Like, + Newsroom, OauthClient, Profile, Report, @@ -258,4 +259,153 @@ class AdminController extends Controller $message->save(); return; } + + public function newsroomHome(Request $request) + { + $newsroom = Newsroom::latest()->paginate(10); + return view('admin.newsroom.home', compact('newsroom')); + } + + public function newsroomCreate(Request $request) + { + return view('admin.newsroom.create'); + } + + public function newsroomEdit(Request $request, $id) + { + $news = Newsroom::findOrFail($id); + return view('admin.newsroom.edit', compact('news')); + } + + public function newsroomDelete(Request $request, $id) + { + $news = Newsroom::findOrFail($id); + $news->delete(); + return redirect('/i/admin/newsroom'); + } + + public function newsroomUpdate(Request $request, $id) + { + $this->validate($request, [ + 'title' => 'required|string|min:1|max:100', + 'summary' => 'nullable|string|max:200', + 'body' => 'nullable|string' + ]); + $changed = false; + $changedFields = []; + $news = Newsroom::findOrFail($id); + $fields = [ + 'title' => 'string', + 'summary' => 'string', + 'body' => 'string', + 'category' => 'string', + 'show_timeline' => 'boolean', + 'auth_only' => 'boolean', + 'show_link' => 'boolean', + 'force_modal' => 'boolean', + 'published' => 'published' + ]; + foreach($fields as $field => $type) { + switch ($type) { + case 'string': + if($request->{$field} != $news->{$field}) { + if($field == 'title') { + $news->slug = str_slug($request->{$field}); + } + $news->{$field} = $request->{$field}; + $changed = true; + array_push($changedFields, $field); + } + break; + + case 'boolean': + $state = $request->{$field} == 'on' ? true : false; + if($state != $news->{$field}) { + $news->{$field} = $state; + $changed = true; + array_push($changedFields, $field); + } + break; + case 'published': + $state = $request->{$field} == 'on' ? true : false; + $published = $news->published_at != null; + if($state != $published) { + $news->published_at = $state ? now() : null; + $changed = true; + array_push($changedFields, $field); + } + break; + + } + } + + if($changed) { + $news->save(); + } + $redirect = $news->published_at ? $news->permalink() : $news->editUrl(); + return redirect($redirect); + } + + + public function newsroomStore(Request $request) + { + $this->validate($request, [ + 'title' => 'required|string|min:1|max:100', + 'summary' => 'nullable|string|max:200', + 'body' => 'nullable|string' + ]); + $changed = false; + $changedFields = []; + $news = new Newsroom(); + $fields = [ + 'title' => 'string', + 'summary' => 'string', + 'body' => 'string', + 'category' => 'string', + 'show_timeline' => 'boolean', + 'auth_only' => 'boolean', + 'show_link' => 'boolean', + 'force_modal' => 'boolean', + 'published' => 'published' + ]; + foreach($fields as $field => $type) { + switch ($type) { + case 'string': + if($request->{$field} != $news->{$field}) { + if($field == 'title') { + $news->slug = str_slug($request->{$field}); + } + $news->{$field} = $request->{$field}; + $changed = true; + array_push($changedFields, $field); + } + break; + + case 'boolean': + $state = $request->{$field} == 'on' ? true : false; + if($state != $news->{$field}) { + $news->{$field} = $state; + $changed = true; + array_push($changedFields, $field); + } + break; + case 'published': + $state = $request->{$field} == 'on' ? true : false; + $published = $news->published_at != null; + if($state != $published) { + $news->published_at = $state ? now() : null; + $changed = true; + array_push($changedFields, $field); + } + break; + + } + } + + if($changed) { + $news->save(); + } + $redirect = $news->published_at ? $news->permalink() : $news->editUrl(); + return redirect($redirect); + } } diff --git a/app/Http/Controllers/NewsroomController.php b/app/Http/Controllers/NewsroomController.php new file mode 100644 index 000000000..7c2f7adbc --- /dev/null +++ b/app/Http/Controllers/NewsroomController.php @@ -0,0 +1,94 @@ +latest()->paginate(9); + } else { + $posts = Newsroom::whereNotNull('published_at') + ->whereAuthOnly(false) + ->latest() + ->paginate(3); + } + return view('site.news.home', compact('posts')); + } + + public function show(Request $request, $year, $month, $slug) + { + $post = Newsroom::whereNotNull('published_at') + ->whereSlug($slug) + ->whereYear('published_at', $year) + ->whereMonth('published_at', $month) + ->firstOrFail(); + abort_if($post->auth_only && !$request->user(), 404); + return view('site.news.post.show', compact('post')); + } + + public function search(Request $request) + { + abort(404); + $this->validate($request, [ + 'q' => 'nullable' + ]); + } + + public function archive(Request $request) + { + abort(404); + return view('site.news.archive.index'); + } + + public function timelineApi(Request $request) + { + abort_if(!Auth::check(), 404); + + $key = 'newsroom:read:profileid:' . $request->user()->profile_id; + $read = Redis::smembers($key); + + $posts = Newsroom::whereNotNull('published_at') + ->whereShowTimeline(true) + ->whereNotIn('id', $read) + ->orderBy('id', 'desc') + ->take(9) + ->get() + ->map(function($post) { + return [ + 'id' => $post->id, + 'title' => Str::limit($post->title, 25), + 'summary' => $post->summary, + 'url' => $post->show_link ? $post->permalink() : null, + 'published_at' => $post->published_at->format('F m, Y') + ]; + }); + return response()->json($posts, 200, [], JSON_PRETTY_PRINT); + } + + public function markAsRead(Request $request) + { + abort_if(!Auth::check(), 404); + + $this->validate($request, [ + 'id' => 'required|integer|min:1' + ]); + + $news = Newsroom::whereNotNull('published_at') + ->findOrFail($request->input('id')); + + $key = 'newsroom:read:profileid:' . $request->user()->profile_id; + + Redis::sadd($key, $news->id); + + return response()->json(['code' => 200]); + } +} diff --git a/app/Newsroom.php b/app/Newsroom.php new file mode 100644 index 000000000..eca57eafc --- /dev/null +++ b/app/Newsroom.php @@ -0,0 +1,27 @@ +published_at->year; + $month = $this->published_at->format('m'); + $slug = $this->slug; + + return url("/site/newsroom/{$year}/{$month}/{$slug}"); + } + + public function editUrl() + { + return url("/i/admin/newsroom/edit/{$this->id}"); + } +} diff --git a/database/migrations/2019_12_10_023604_create_newsroom_table.php b/database/migrations/2019_12_10_023604_create_newsroom_table.php new file mode 100644 index 000000000..2651d5c4d --- /dev/null +++ b/database/migrations/2019_12_10_023604_create_newsroom_table.php @@ -0,0 +1,45 @@ +bigIncrements('id'); + $table->bigInteger('user_id')->unsigned()->nullable(); + $table->string('header_photo_url')->nullable(); + $table->string('title')->nullable(); + $table->string('slug')->nullable()->unique()->index(); + $table->string('category')->default('update'); + $table->text('summary')->nullable(); + $table->text('body')->nullable(); + $table->text('body_rendered')->nullable(); + $table->string('link')->nullable(); + $table->boolean('force_modal')->default(false); + $table->boolean('show_timeline')->default(false); + $table->boolean('show_link')->default(false); + $table->boolean('auth_only')->default(true); + $table->timestamp('published_at')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('site_news'); + } +} diff --git a/public/js/compose-classic.js b/public/js/compose-classic.js index 3c11c0415..143ef3f48 100644 Binary files a/public/js/compose-classic.js and b/public/js/compose-classic.js differ diff --git a/public/js/compose.js b/public/js/compose.js index fd66f001c..9e69d9c66 100644 Binary files a/public/js/compose.js and b/public/js/compose.js differ diff --git a/public/js/profile.js b/public/js/profile.js index 36e38d798..cc260afe2 100644 Binary files a/public/js/profile.js and b/public/js/profile.js differ diff --git a/public/js/status.js b/public/js/status.js index 1c6ce543f..88d8baef6 100644 Binary files a/public/js/status.js and b/public/js/status.js differ diff --git a/public/js/timeline.js b/public/js/timeline.js index 5162342d8..c3e02488f 100644 Binary files a/public/js/timeline.js and b/public/js/timeline.js differ diff --git a/public/mix-manifest.json b/public/mix-manifest.json index cc4135fe0..a5fc352f1 100644 Binary files a/public/mix-manifest.json and b/public/mix-manifest.json differ diff --git a/resources/assets/js/components/AnnouncementsCard.vue b/resources/assets/js/components/AnnouncementsCard.vue new file mode 100644 index 000000000..4e43b4857 --- /dev/null +++ b/resources/assets/js/components/AnnouncementsCard.vue @@ -0,0 +1,155 @@ + + + + + \ No newline at end of file diff --git a/resources/assets/js/components/NotificationCard.vue b/resources/assets/js/components/NotificationCard.vue index cd9c9379b..ad16298c8 100644 --- a/resources/assets/js/components/NotificationCard.vue +++ b/resources/assets/js/components/NotificationCard.vue @@ -1,5 +1,6 @@ diff --git a/resources/assets/js/components/Timeline.vue b/resources/assets/js/components/Timeline.vue index 5fdefebc7..0f38efdca 100644 --- a/resources/assets/js/components/Timeline.vue +++ b/resources/assets/js/components/Timeline.vue @@ -90,41 +90,6 @@ - @@ -281,21 +246,13 @@
- Compose Post + + Compose Post +
-
-
-
-
- Tip: Hide follower counts - -
-

- You can hide followers or following count and lists on your profile. -
Privacy Settings

-
-
+
+
@@ -565,7 +522,6 @@ beforeMount() { this.fetchProfile(); this.fetchTimelineApi(); - }, mounted() { @@ -1359,11 +1315,6 @@ this.$refs.ctxModModal.hide(); }, - hideTips() { - this.showTips = false; - window.localStorage.setItem('metro-tips', false); - }, - formatCount(count) { return App.util.format.count(count); }, @@ -1431,7 +1382,7 @@ return _.truncate(caption, { length: len }); - } + }, } } \ No newline at end of file diff --git a/resources/assets/js/timeline.js b/resources/assets/js/timeline.js index 849fa5f26..0e8b1488a 100644 --- a/resources/assets/js/timeline.js +++ b/resources/assets/js/timeline.js @@ -36,4 +36,9 @@ Vue.component( Vue.component( 'timeline', require('./components/Timeline.vue').default +); + +Vue.component( + 'announcements-card', + require('./components/AnnouncementsCard.vue').default ); \ No newline at end of file diff --git a/resources/views/admin/newsroom/create.blade.php b/resources/views/admin/newsroom/create.blade.php new file mode 100644 index 000000000..575c21d82 --- /dev/null +++ b/resources/views/admin/newsroom/create.blade.php @@ -0,0 +1,135 @@ +@extends('admin.partial.template-full') + +@section('section') +
+
+
+ +
+

Newsroom

+

Create Announcement

+
+ +
+
+
+
+
+
+ @csrf +
+ + +

We recommend titles shorter than 80 characters.

+
+
+ + +
+
+ + +

Click here to enable the rich text editor.

+
+
+ + +
+
+ +
+
+ +
+
+
+ Untitled + +
+

+ Add a summary +

+

+ Read more + + + + + + + + + + + +

+
+
+
+

+ +

+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+{{--
+
+ + +
+
--}} + +
+
+
+ @method('delete') + @csrf +
+@endsection + +@push('scripts') + +@endpush \ No newline at end of file diff --git a/resources/views/admin/newsroom/edit.blade.php b/resources/views/admin/newsroom/edit.blade.php new file mode 100644 index 000000000..c98a23378 --- /dev/null +++ b/resources/views/admin/newsroom/edit.blade.php @@ -0,0 +1,141 @@ +@extends('admin.partial.template-full') + +@section('section') +
+
+
+ +
+

Newsroom

+

Edit Announcement

+
+ +
+
+
+
+
+
+ @csrf +
+ + +

We recommend titles shorter than 80 characters.

+
+
+ + +
+
+ + +

Click here to enable the rich text editor.

+
+
+ + +
+
+ +
+
+ +
+
+
+ {{$news->title}} + +
+

+ {{$news->summary}} +

+

+ Read more + + + + + + + + + + + +

+
+
+
+

+ +

+
+
+ published_at ? 'checked="checked"' : ''}}> + +
+
+
+
+ show_timeline ? 'checked="checked"' : ''}}> + +
+
+
+
+ auth_only ? 'checked="checked"' : ''}}> + +
+
+
+
+ show_link ? 'checked="checked"' : ''}}> + +
+
+ {{--
+
+ force_modal ? 'checked="checked"' : ''}}> + +
+
--}} +
+ +

+ + +

+ +
+
+
+@method('delete') +@csrf +
+@endsection + +@push('scripts') + +@endpush \ No newline at end of file diff --git a/resources/views/admin/newsroom/home.blade.php b/resources/views/admin/newsroom/home.blade.php new file mode 100644 index 000000000..78976bd71 --- /dev/null +++ b/resources/views/admin/newsroom/home.blade.php @@ -0,0 +1,62 @@ +@extends('admin.partial.template-full') + +@section('section') +
+ +
+

Newsroom

+

Manage News and Platform Tips

+
+ +
+ New Announcement + View Newsroom +
+
+ +
+
+
+
+ Announcements +
+ @if($newsroom->count() > 0) +
    + @foreach($newsroom as $news) +
  • +
    +

    {{str_limit($news->title,30)}}

    +

    {{str_limit($news->summary, 40)}}

    +
    +
    + @if($news->published_at != null) + PUBLISHED + @else + DRAFT + @endif + + + + @if($news->published_at) + + + + @endif +
    +
  • + @endforeach +
+ @else +
+

No Announcements Found!

+
+ @endif +
+
+ {!!$newsroom->links()!!} +
+
+ +
+ +@endsection diff --git a/resources/views/admin/partial/topnav.blade.php b/resources/views/admin/partial/topnav.blade.php index 2a6ee4952..c0ca084d6 100644 --- a/resources/views/admin/partial/topnav.blade.php +++ b/resources/views/admin/partial/topnav.blade.php @@ -1,4 +1,4 @@ -