From 23ecc26978cb5eccc55b3759a8f6c282624e22d9 Mon Sep 17 00:00:00 2001 From: Viktor Geringer Date: Thu, 27 Dec 2018 21:35:41 +0100 Subject: [PATCH] Feature/reminder (#110) * move refresh in tab, add job for refresh, add new setting * check for setting in kernel * prepare frontend and database for reminders * prepare mail settings * add timezone config * add security-advisories package * set back APP_URL * send daily reminder * update headlines for daily reminder * fix postgres id sequence on import * some basic responsive behaviour * add weekly reminder * fix footer css * update readme * change loading logo --- README.md | 12 +- backend/.env.example | 14 + backend/app/Console/Commands/Daily.php | 26 + backend/app/Console/Commands/Init.php | 5 - backend/app/Console/Commands/Refresh.php | 27 + backend/app/Console/Commands/Weekly.php | 26 + backend/app/Console/Kernel.php | 28 +- .../Controllers/ExportImportController.php | 18 +- .../Http/Controllers/SettingController.php | 35 + backend/app/Jobs/ImportEpisode.php | 4 +- backend/app/Jobs/ImportItem.php | 2 - backend/app/Jobs/UpdateItem.php | 42 +- backend/app/Mail/DailyReminder.php | 51 + backend/app/Mail/WeeklyReminder.php | 57 + backend/app/Services/Models/ItemService.php | 4 +- backend/app/Services/Reminder.php | 63 + backend/app/Setting.php | 3 + backend/composer.json | 5 +- backend/composer.lock | 43 +- backend/config/app.php | 3 +- backend/config/mail.php | 2 +- ...180540_add_refresh_automatically_field.php | 17 + ..._10_180653_add_reminders_send_to_field.php | 17 + ..._10_180828_add_daily_and_weekly_fields.php | 18 + backend/routes/console.php | 2 + backend/routes/web.php | 3 + backend/tests/Setting/SettingTest.php | 50 +- .../app/components/Content/Settings/Index.vue | 10 +- .../app/components/Content/Settings/Misc.vue | 21 +- .../components/Content/Settings/Options.vue | 2 +- .../components/Content/Settings/Refresh.vue | 80 + .../components/Content/Settings/Reminders.vue | 97 + client/app/components/Content/Subpage.vue | 1 - client/app/components/Footer.vue | 2 +- client/app/components/Header.vue | 15 +- client/package-lock.json | 1792 +++++++++++++---- client/package.json | 4 +- client/resources/languages/ar.json | 9 + client/resources/languages/da.json | 9 + client/resources/languages/de.json | 9 + client/resources/languages/el.json | 9 + client/resources/languages/en.json | 9 + client/resources/languages/es.json | 10 + client/resources/languages/fr.json | 9 + client/resources/languages/nl.json | 9 + client/resources/languages/ru.json | 9 + .../resources/mails/compiled/daily.blade.php | 322 +++ .../resources/mails/compiled/weekly.blade.php | 322 +++ .../mails/templates/daily.mjml.blade.php | 92 + .../mails/templates/weekly.mjml.blade.php | 92 + client/resources/sass/_base.scss | 8 +- client/resources/sass/_misc.scss | 10 + .../resources/sass/components/_content.scss | 6 +- client/resources/sass/components/_footer.scss | 21 +- client/resources/sass/components/_header.scss | 77 +- client/resources/sass/components/_login.scss | 1 + .../resources/sass/components/_subpage.scss | 69 +- public/assets/img/hamburger.png | Bin 0 -> 279 bytes 58 files changed, 3143 insertions(+), 560 deletions(-) create mode 100644 backend/app/Console/Commands/Daily.php create mode 100644 backend/app/Console/Commands/Refresh.php create mode 100644 backend/app/Console/Commands/Weekly.php create mode 100644 backend/app/Mail/DailyReminder.php create mode 100644 backend/app/Mail/WeeklyReminder.php create mode 100644 backend/app/Services/Reminder.php create mode 100644 backend/database/migrations/2018_11_10_180540_add_refresh_automatically_field.php create mode 100644 backend/database/migrations/2018_11_10_180653_add_reminders_send_to_field.php create mode 100644 backend/database/migrations/2018_11_10_180828_add_daily_and_weekly_fields.php create mode 100644 client/app/components/Content/Settings/Refresh.vue create mode 100644 client/app/components/Content/Settings/Reminders.vue create mode 100644 client/resources/mails/compiled/daily.blade.php create mode 100644 client/resources/mails/compiled/weekly.blade.php create mode 100644 client/resources/mails/templates/daily.mjml.blade.php create mode 100644 client/resources/mails/templates/weekly.mjml.blade.php create mode 100644 public/assets/img/hamburger.png diff --git a/README.md b/README.md index 469e730..a76b8ab 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ If you go to the settings page of your installation, flox will automatically che ### Queue -To import or update any of your entries you need to have at least one worker running. +To import or refresh any of your entries you need to have at least one worker running. ```bash # spawn a single worker @@ -112,6 +112,16 @@ The import will download all poster images. After the import, you can refresh the complete data (add missing episodes, update ratings and more) in the settings page. +### Refresh data + +To keep your entries up to date (e.g. ratings, episodes, images) you need to refresh them. In the settings there is the possibility to refresh the data manually or via a cron job (you need the queue worker for this). If you want to refresh only a single entry, there is a button on the subpage of this item. + +### Reminders + +Flox can send you a daily reminder of episodes or movies coming out today via mail. Or a weekly summary of episodes and movies coming out in the last 7 days. There are options in the settings page for this. + +Make sure you tweak the `DATE_FORMAT_PATTERN` config in your `.env` file. + ### Translation All titles are in english by default. You can change your language by setting `TRANSLATION` in `backend/.env`. The most commons are `DE`, `IT`, `FR`, `ES` and `RU`. You can try to use your language code. diff --git a/backend/.env.example b/backend/.env.example index 44b94ac..c00d501 100644 --- a/backend/.env.example +++ b/backend/.env.example @@ -7,6 +7,12 @@ LOADING_ITEMS=30 # Default 10 minutes (600 seconds) PHP_TIME_LIMIT=600 +# Set your correct timezone +TIMEZONE=UTC + +# Date pattern for reminder mails +DATE_FORMAT_PATTERN=d.m.Y + DB_CONNECTION=mysql DB_HOST=localhost DB_PORT=3306 @@ -14,6 +20,7 @@ DB_DATABASE= DB_USERNAME= DB_PASSWORD= +APP_URL=http://localhost APP_ENV=local APP_KEY= APP_DEBUG=true @@ -24,3 +31,10 @@ QUEUE_DRIVER=database FP_HOST=localhost FP_PORT=3000 + +MAIL_DRIVER=smtp +MAIL_HOST=smtp.mailtrap.io +MAIL_PORT=2525 +MAIL_USERNAME=null +MAIL_PASSWORD=null +MAIL_ENCRYPTION=null diff --git a/backend/app/Console/Commands/Daily.php b/backend/app/Console/Commands/Daily.php new file mode 100644 index 0000000..144cae9 --- /dev/null +++ b/backend/app/Console/Commands/Daily.php @@ -0,0 +1,26 @@ +reminder = $reminder; + } + + public function handle() + { + $this->reminder->sendDaily(); + } + } diff --git a/backend/app/Console/Commands/Init.php b/backend/app/Console/Commands/Init.php index 8d998e1..2914b42 100644 --- a/backend/app/Console/Commands/Init.php +++ b/backend/app/Console/Commands/Init.php @@ -9,11 +9,6 @@ protected $signature = 'flox:init {database?} {username?} {password?}'; protected $description = 'Create .env file, set the app key and fill database credentials'; - public function __construct() - { - parent::__construct(); - } - public function handle() { $this->createENVFile(); diff --git a/backend/app/Console/Commands/Refresh.php b/backend/app/Console/Commands/Refresh.php new file mode 100644 index 0000000..bb4a4d1 --- /dev/null +++ b/backend/app/Console/Commands/Refresh.php @@ -0,0 +1,27 @@ +itemService = $itemService; + } + + public function handle() + { + $this->callSilent('queue:clear'); + $this->itemService->refreshAll(); + } + } diff --git a/backend/app/Console/Commands/Weekly.php b/backend/app/Console/Commands/Weekly.php new file mode 100644 index 0000000..1521cbb --- /dev/null +++ b/backend/app/Console/Commands/Weekly.php @@ -0,0 +1,26 @@ +reminder = $reminder; + } + + public function handle() + { + $this->reminder->sendWeekly(); + } + } diff --git a/backend/app/Console/Kernel.php b/backend/app/Console/Kernel.php index 9f42f74..22679bc 100644 --- a/backend/app/Console/Kernel.php +++ b/backend/app/Console/Kernel.php @@ -2,8 +2,13 @@ namespace App\Console; +use App\Console\Commands\Daily; +use App\Console\Commands\Refresh; +use App\Console\Commands\Weekly; +use App\Setting; use Illuminate\Console\Scheduling\Schedule; use Illuminate\Foundation\Console\Kernel as ConsoleKernel; +use Illuminate\Support\Facades\Schema; class Kernel extends ConsoleKernel { @@ -15,6 +20,9 @@ class Kernel extends ConsoleKernel protected $commands = [ Commands\Init::class, Commands\DB::class, + Refresh::class, + Daily::class, + Weekly::class, ]; /** @@ -25,7 +33,25 @@ class Kernel extends ConsoleKernel */ protected function schedule(Schedule $schedule) { - $schedule->call("\App\Services\Models\ItemService@refreshAll")->daily(); + if(app()->runningUnitTests()) { + return null; + } + + if (Schema::hasTable('settings')) { + $settings = Setting::first(); + + if ($settings->refresh_automatically) { + $schedule->command(Refresh::class)->dailyAt('06:00'); + } + + if ($settings->daily_reminder) { + $schedule->command(Daily::class)->dailyAt('07:00'); + } + + if ($settings->weekly_reminder) { + $schedule->command(Weekly::class)->saturdays()->at('18:00'); + } + } } /** diff --git a/backend/app/Http/Controllers/ExportImportController.php b/backend/app/Http/Controllers/ExportImportController.php index 1c1f5a1..aad3005 100644 --- a/backend/app/Http/Controllers/ExportImportController.php +++ b/backend/app/Http/Controllers/ExportImportController.php @@ -7,10 +7,8 @@ use App\AlternativeTitle; use App\Episode; use App\Item; - use App\Services\Models\ItemService; use App\Services\Storage; use App\Setting; - use Carbon\Carbon; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Input; use Symfony\Component\HttpFoundation\Response; @@ -20,7 +18,6 @@ private $item; private $episodes; private $storage; - private $version; private $alternativeTitles; private $settings; @@ -31,7 +28,6 @@ $this->alternativeTitles = $alternativeTitles; $this->storage = $storage; $this->settings = $settings; - $this->version = config('app.version'); } /** @@ -90,30 +86,34 @@ ImportItem::dispatch(json_encode($item)); } } + logInfo("Import Movies done."); } private function importEpisodes($data) { logInfo("Import Tv Shows"); + if(isset($data->episodes)) { - $this->episodes->truncate(); + foreach(array_chunk($data->episodes, 50) as $chunk) { ImportEpisode::dispatch(json_encode($chunk)); } } + logInfo("Import Tv Shows done."); } private function importAlternativeTitles($data) { if(isset($data->alternative_titles)) { - $this->alternativeTitles->truncate(); foreach($data->alternative_titles as $title) { - $this->alternativeTitles->create((array) $title); + $title = collect($title)->except('id')->toArray(); + + $this->alternativeTitles->create($title); } } } @@ -125,7 +125,9 @@ $this->settings->truncate(); foreach($data->settings as $setting) { - $this->settings->create((array) $setting); + $setting = collect($setting)->except('id')->toArray(); + + $this->settings->create($setting); } } } diff --git a/backend/app/Http/Controllers/SettingController.php b/backend/app/Http/Controllers/SettingController.php index d11d2f0..fdc4b09 100644 --- a/backend/app/Http/Controllers/SettingController.php +++ b/backend/app/Http/Controllers/SettingController.php @@ -60,6 +60,10 @@ 'version' => $this->version, 'watchlist' => $settings->show_watchlist_everywhere, 'ratings' => $settings->show_ratings, + 'refresh' => $settings->refresh_automatically, + 'reminders_send_to' => $settings->reminders_send_to, + 'daily' => $settings->daily_reminder, + 'weekly' => $settings->weekly_reminder, ]; } @@ -88,4 +92,35 @@ 'show_ratings' => Input::get('ratings'), ]); } + + /** + * Update refresh check. + */ + public function updateRefresh() + { + $this->setting->first()->update([ + 'refresh_automatically' => Input::get('refresh'), + ]); + } + + /** + * Update reminders mail. + */ + public function updateRemindersSendTo() + { + $this->setting->first()->update([ + 'reminders_send_to' => Input::get('reminders_send_to'), + ]); + } + + /** + * Update reminder options. + */ + public function updateReminderOptions() + { + $this->setting->first()->update([ + 'daily_reminder' => Input::get('daily'), + 'weekly_reminder' => Input::get('weekly'), + ]); + } } diff --git a/backend/app/Jobs/ImportEpisode.php b/backend/app/Jobs/ImportEpisode.php index 8e9006c..22e2f43 100644 --- a/backend/app/Jobs/ImportEpisode.php +++ b/backend/app/Jobs/ImportEpisode.php @@ -38,7 +38,9 @@ class ImportEpisode implements ShouldQueue foreach($this->episodes as $ep) { logInfo("Importing episode", [$ep->name]); try { - $episode->create((array) $ep); + $ep = collect($ep)->except('id')->toArray(); + + $episode->create($ep); } catch(\Exception $e) { logInfo("Failed:", [$e]); throw $e; diff --git a/backend/app/Jobs/ImportItem.php b/backend/app/Jobs/ImportItem.php index 4d3ed9b..96ac97d 100644 --- a/backend/app/Jobs/ImportItem.php +++ b/backend/app/Jobs/ImportItem.php @@ -2,9 +2,7 @@ namespace App\Jobs; -use App\Item; use App\Services\Models\ItemService; -use App\Services\Storage; use Illuminate\Bus\Queueable; use Illuminate\Queue\SerializesModels; use Illuminate\Queue\InteractsWithQueue; diff --git a/backend/app/Jobs/UpdateItem.php b/backend/app/Jobs/UpdateItem.php index 5e82d3b..fd37940 100644 --- a/backend/app/Jobs/UpdateItem.php +++ b/backend/app/Jobs/UpdateItem.php @@ -11,36 +11,36 @@ use Illuminate\Foundation\Bus\Dispatchable; class UpdateItem implements ShouldQueue { - use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; + use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; - protected $itemId; + protected $itemId; - /** - * Create a new job instance. - * - * @return void - */ - public function __construct($itemId) - { - $this->itemId = $itemId; - } + /** + * Create a new job instance. + * + * @param $itemId + */ + public function __construct($itemId) + { + $this->itemId = $itemId; + } /** * Execute the job. * * @param ItemService $itemService - * + * * @return void - * + * * @throws \Exception */ - public function handle(ItemService $itemService) - { - try { - $itemService->refresh($this->itemId); - } catch(\Exception $e) { - logInfo("Failed:", [$e]); - throw $e; - } + public function handle(ItemService $itemService) + { + try { + $itemService->refresh($this->itemId); + } catch (\Exception $e) { + logInfo("Failed:", [$e]); + throw $e; } + } } diff --git a/backend/app/Mail/DailyReminder.php b/backend/app/Mail/DailyReminder.php new file mode 100644 index 0000000..35993cb --- /dev/null +++ b/backend/app/Mail/DailyReminder.php @@ -0,0 +1,51 @@ +episodes = $episodes; + $this->movies = $movies; + } + + /** + * Build the message. + * + * @param Storage $storage + * + * @return $this + */ + public function build(Storage $storage) + { + $lang = collect(json_decode($storage->parseLanguage())); + $headline = $lang['daily reminder']; + $date = date(config('app.DATE_FORMAT_PATTERN')); + + return $this->view('mails.compiled.daily')->with([ + 'headline' => $headline, + 'episodesHeadline' => $lang['episodes today'], + 'moviesHeadline' => $lang['movies today'], + 'episodes' => $this->episodes, + 'movies' => $this->movies, + 'date' => $date, + ])->subject("$headline $date"); + } +} diff --git a/backend/app/Mail/WeeklyReminder.php b/backend/app/Mail/WeeklyReminder.php new file mode 100644 index 0000000..21167e0 --- /dev/null +++ b/backend/app/Mail/WeeklyReminder.php @@ -0,0 +1,57 @@ +episodes = $episodes; + $this->movies = $movies; + $this->startWeek = date(config('app.DATE_FORMAT_PATTERN'), $startWeek); + $this->endWeek = date(config('app.DATE_FORMAT_PATTERN'), $endWeek); + } + + /** + * Build the message. + * + * @param Storage $storage + * + * @return $this + */ + public function build(Storage $storage) + { + $lang = collect(json_decode($storage->parseLanguage())); + $headline = $lang['weekly reminder']; + $date = $this->startWeek . ' - ' . $this->endWeek; + + return $this->view('mails.compiled.weekly')->with([ + 'headline' => $headline, + 'episodes' => $this->episodes, + 'movies' => $this->movies, + 'episodesHeadline' => $lang['episodes'], + 'moviesHeadline' => $lang['movies'], + 'date' => $date, + ])->subject("$headline $date"); + } +} diff --git a/backend/app/Services/Models/ItemService.php b/backend/app/Services/Models/ItemService.php index c3fc4ae..ccf910a 100644 --- a/backend/app/Services/Models/ItemService.php +++ b/backend/app/Services/Models/ItemService.php @@ -356,7 +356,9 @@ $this->storage->downloadImages($item['poster'], $item['backdrop']); } - Item::create((array) $item); + $item = collect($item)->except('id')->toArray(); + + Item::create($item); } /** diff --git a/backend/app/Services/Reminder.php b/backend/app/Services/Reminder.php new file mode 100644 index 0000000..e2c8799 --- /dev/null +++ b/backend/app/Services/Reminder.php @@ -0,0 +1,63 @@ +startOfDay()->timestamp; + $endToday = today()->endOfDay()->timestamp; + + $episodes = Episode::whereBetween('release_episode', [$startToday, $endToday]) + ->with('item') + ->orderBy('tmdb_id') + ->get(); + + $movies = Item::where('media_type', 'movie') + ->whereBetween('released', [$startToday, $endToday]) + ->get(); + + if (count($episodes) || count($movies)) { + Mail::to($settings->reminders_send_to) + ->send(new DailyReminder($episodes, $movies)); + } + } + + /** + * Send a weekly summary. + */ + public function sendWeekly() + { + $settings = Setting::first(); + + $startWeek = today()->startOfWeek()->timestamp; + $endWeek = today()->endOfWeek()->timestamp; + + $episodes = Episode::whereBetween('release_episode', [$startWeek, $endWeek]) + ->with('item') + ->orderBy('tmdb_id') + ->get(); + + $movies = Item::where('media_type', 'movie') + ->whereBetween('released', [$startWeek, $endWeek]) + ->get(); + + if (count($episodes) || count($movies)) { + Mail::to($settings->reminders_send_to) + ->send(new WeeklyReminder($episodes, $movies, $startWeek, $endWeek)); + } + } + } diff --git a/backend/app/Setting.php b/backend/app/Setting.php index d71f944..462f9f7 100644 --- a/backend/app/Setting.php +++ b/backend/app/Setting.php @@ -38,5 +38,8 @@ 'show_genre' => 'boolean', 'episode_spoiler_protection' => 'boolean', 'show_watchlist_everywhere' => 'boolean', + 'refresh_automatically' => 'boolean', + 'daily_reminder' => 'boolean', + 'weekly_reminder' => 'boolean', ]; } diff --git a/backend/composer.json b/backend/composer.json index ff5a078..5c4832f 100644 --- a/backend/composer.json +++ b/backend/composer.json @@ -19,9 +19,12 @@ "guzzlehttp/guzzle": "^6.3", "imangazaliev/didom": "^1.13", "laravel/framework": "5.7.*", - "laravel/tinker": "^1.0" + "laravel/tinker": "^1.0", + "morrislaptop/laravel-queue-clear": "^1.1", + "ext-json": "*" }, "require-dev": { + "roave/security-advisories": "dev-master", "filp/whoops": "~2.0", "fzaninotto/faker": "~1.4", "laravel/telescope": "^0.1.7", diff --git a/backend/composer.lock b/backend/composer.lock index 8227115..0d7b727 100644 --- a/backend/composer.lock +++ b/backend/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "cf5202abb7de87ccf7e8f79f018d72a2", + "content-hash": "7c42445afb3d31be041791569951f35f", "packages": [ { "name": "dnoegel/php-xdg-base-dir", @@ -1278,6 +1278,47 @@ ], "time": "2018-11-05T09:00:11+00:00" }, + { + "name": "morrislaptop/laravel-queue-clear", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/morrislaptop/laravel-queue-clear.git", + "reference": "ea814b360322fcdf2e9397b7a77b1ce4e96423a4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/morrislaptop/laravel-queue-clear/zipball/ea814b360322fcdf2e9397b7a77b1ce4e96423a4", + "reference": "ea814b360322fcdf2e9397b7a77b1ce4e96423a4", + "shasum": "" + }, + "require": { + "illuminate/support": ">=5.0.0", + "php": ">=5.4.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Morrislaptop\\LaravelQueueClear\\LaravelQueueClearServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Morrislaptop\\LaravelQueueClear\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "authors": [ + { + "name": "Craig Morris", + "email": "craig.michael.morris@gmail.com" + } + ], + "description": "Command for wiping your queues clear", + "time": "2017-09-04T08:02:44+00:00" + }, { "name": "nesbot/carbon", "version": "1.34.1", diff --git a/backend/config/app.php b/backend/config/app.php index 7c94bbf..42af3c8 100644 --- a/backend/config/app.php +++ b/backend/config/app.php @@ -9,6 +9,7 @@ 'LOADING_ITEMS' => env('LOADING_ITEMS'), 'CLIENT_URI' => env('CLIENT_URI'), 'PHP_TIME_LIMIT' => env('PHP_TIME_LIMIT'), + 'DATE_FORMAT_PATTERN' => env('DATE_FORMAT_PATTERN'), /* |-------------------------------------------------------------------------- @@ -72,7 +73,7 @@ | */ - 'timezone' => 'UTC', + 'timezone' => env('TIMEZONE', 'UTC'), /* |-------------------------------------------------------------------------- diff --git a/backend/config/mail.php b/backend/config/mail.php index 9d4c4d8..4c1c630 100644 --- a/backend/config/mail.php +++ b/backend/config/mail.php @@ -57,7 +57,7 @@ return [ 'from' => [ 'address' => 'hello@example.com', - 'name' => 'Example', + 'name' => 'Flox', ], /* diff --git a/backend/database/migrations/2018_11_10_180540_add_refresh_automatically_field.php b/backend/database/migrations/2018_11_10_180540_add_refresh_automatically_field.php new file mode 100644 index 0000000..551170d --- /dev/null +++ b/backend/database/migrations/2018_11_10_180540_add_refresh_automatically_field.php @@ -0,0 +1,17 @@ +boolean('refresh_automatically')->default(0); + }); + } + + public function down() {} +} diff --git a/backend/database/migrations/2018_11_10_180653_add_reminders_send_to_field.php b/backend/database/migrations/2018_11_10_180653_add_reminders_send_to_field.php new file mode 100644 index 0000000..7444376 --- /dev/null +++ b/backend/database/migrations/2018_11_10_180653_add_reminders_send_to_field.php @@ -0,0 +1,17 @@ +string('reminders_send_to')->nullable(); + }); + } + + public function down() {} +} diff --git a/backend/database/migrations/2018_11_10_180828_add_daily_and_weekly_fields.php b/backend/database/migrations/2018_11_10_180828_add_daily_and_weekly_fields.php new file mode 100644 index 0000000..44a1d1c --- /dev/null +++ b/backend/database/migrations/2018_11_10_180828_add_daily_and_weekly_fields.php @@ -0,0 +1,18 @@ +boolean('daily_reminder')->default(0); + $table->boolean('weekly_reminder')->default(0); + }); + } + + public function down() {} +} diff --git a/backend/routes/console.php b/backend/routes/console.php index e69de29..a4abe2d 100644 --- a/backend/routes/console.php +++ b/backend/routes/console.php @@ -0,0 +1,2 @@ +group(function() { Route::get('/check-update', 'SettingController@checkForUpdate'); Route::get('/version', 'SettingController@getVersion'); + Route::patch('/settings/refresh', 'SettingController@updateRefresh'); + Route::patch('/settings/reminders-send-to', 'SettingController@updateRemindersSendTo'); + Route::patch('/settings/reminder-options', 'SettingController@updateReminderOptions'); Route::patch('/settings', 'SettingController@updateSettings'); Route::post('/add', 'ItemController@add'); diff --git a/backend/tests/Setting/SettingTest.php b/backend/tests/Setting/SettingTest.php index 05446af..404aeb0 100644 --- a/backend/tests/Setting/SettingTest.php +++ b/backend/tests/Setting/SettingTest.php @@ -24,8 +24,6 @@ /** @test */ public function user_can_change_settings() { - $this->getJson('api/settings'); - $oldSettings = Setting::first(); $this->actingAs($this->user)->patchJson('api/settings', [ @@ -49,4 +47,52 @@ $this->assertEquals(1, $newSettings->show_watchlist_everywhere); $this->assertEquals('hover', $newSettings->show_ratings); } + + /** @test */ + public function user_can_change_refresh() + { + $oldSettings = Setting::first(); + + $this->actingAs($this->user)->patchJson('api/settings/refresh', [ + 'refresh' => 1, + ]); + + $newSettings = Setting::first(); + + $this->assertEquals(0, $oldSettings->refresh_automatically); + $this->assertEquals(1, $newSettings->refresh_automatically); + } + + /** @test */ + public function user_can_change_reminders_send_to() + { + $oldSettings = Setting::first(); + + $this->actingAs($this->user)->patchJson('api/settings/reminders-send-to', [ + 'reminders_send_to' => 'jon@snow.io', + ]); + + $newSettings = Setting::first(); + + $this->assertNull($oldSettings->reminders_send_to); + $this->assertEquals('jon@snow.io', $newSettings->reminders_send_to); + } + + /** @test */ + public function user_can_change_reminder_options() + { + $oldSettings = Setting::first(); + + $this->actingAs($this->user)->patchJson('api/settings/reminder-options', [ + 'daily' => 1, + 'weekly' => 1, + ]); + + $newSettings = Setting::first(); + + $this->assertEquals(0, $oldSettings->daily_reminder); + $this->assertEquals(0, $oldSettings->weekly_reminder); + $this->assertEquals(1, $newSettings->daily_reminder); + $this->assertEquals(1, $newSettings->weekly_reminder); + } } diff --git a/client/app/components/Content/Settings/Index.vue b/client/app/components/Content/Settings/Index.vue index 34c4287..f0ac6b0 100644 --- a/client/app/components/Content/Settings/Index.vue +++ b/client/app/components/Content/Settings/Index.vue @@ -7,6 +7,8 @@ {{ lang('tab user') }} {{ lang('tab options') }} {{ lang('tab backup') }} + {{ lang('refresh') }} + {{ lang('reminders') }} @@ -15,6 +17,8 @@ + + @@ -25,6 +29,8 @@ import Options from './Options.vue'; import Backup from './Backup.vue'; import Misc from './Misc.vue'; + import Refresh from './Refresh.vue'; + import Reminders from './Reminders.vue'; import { mapState, mapActions } from 'vuex'; import MiscHelper from '../../../helpers/misc'; @@ -37,7 +43,7 @@ }, components: { - User, Options, Backup, Misc + User, Options, Backup, Misc, Refresh, Reminders }, data() { @@ -60,4 +66,4 @@ } } } - \ No newline at end of file + diff --git a/client/app/components/Content/Settings/Misc.vue b/client/app/components/Content/Settings/Misc.vue index 16dab0a..e5d6f26 100644 --- a/client/app/components/Content/Settings/Misc.vue +++ b/client/app/components/Content/Settings/Misc.vue @@ -10,11 +10,9 @@ {{ lang('feedback') }} GitHub -
- - - {{ lang('refresh all triggered') }} -
+ + + @@ -37,8 +35,6 @@ return { version: '', isUpdate: null, - refreshAllClicked: false, - showRefreshAllMessage: false, } }, @@ -83,17 +79,6 @@ this.SET_LOADING(false); this.version = response.data.version; }); - }, - - refreshAll() { - this.refreshAllClicked = true; - - http.patch(`${config.api}/refresh-all`).then(() => { - this.showRefreshAllMessage = true; - }).catch(error => { - this.refreshAllClicked = false; - alert(error.response.data); - }); } } } diff --git a/client/app/components/Content/Settings/Options.vue b/client/app/components/Content/Settings/Options.vue index a7a61a3..cf6e160 100644 --- a/client/app/components/Content/Settings/Options.vue +++ b/client/app/components/Content/Settings/Options.vue @@ -65,7 +65,7 @@ const data = response.data; this.SET_LOADING(false); - console.log(data) + this.genre = data.genre; this.date = data.date; this.spoiler = data.spoiler; diff --git a/client/app/components/Content/Settings/Refresh.vue b/client/app/components/Content/Settings/Refresh.vue new file mode 100644 index 0000000..398a927 --- /dev/null +++ b/client/app/components/Content/Settings/Refresh.vue @@ -0,0 +1,80 @@ + + + diff --git a/client/app/components/Content/Settings/Reminders.vue b/client/app/components/Content/Settings/Reminders.vue new file mode 100644 index 0000000..71b099f --- /dev/null +++ b/client/app/components/Content/Settings/Reminders.vue @@ -0,0 +1,97 @@ + + + diff --git a/client/app/components/Content/Subpage.vue b/client/app/components/Content/Subpage.vue index 8eaf64d..2f70772 100644 --- a/client/app/components/Content/Subpage.vue +++ b/client/app/components/Content/Subpage.vue @@ -1,6 +1,5 @@