From bb7b05435e9b80ea8f48c4383af5e709ffa65f68 Mon Sep 17 00:00:00 2001 From: shibafu Date: Sun, 8 Nov 2020 01:04:56 +0900 Subject: [PATCH 1/4] add migration --- ...d_discard_elapsed_time_to_ejaculations.php | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 database/migrations/2020_11_08_005107_add_discard_elapsed_time_to_ejaculations.php diff --git a/database/migrations/2020_11_08_005107_add_discard_elapsed_time_to_ejaculations.php b/database/migrations/2020_11_08_005107_add_discard_elapsed_time_to_ejaculations.php new file mode 100644 index 0000000..b81b06c --- /dev/null +++ b/database/migrations/2020_11_08_005107_add_discard_elapsed_time_to_ejaculations.php @@ -0,0 +1,32 @@ +boolean('discard_elapsed_time')->default(false); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('ejaculations', function (Blueprint $table) { + $table->dropColumn('discard_elapsed_time'); + }); + } +} From 855011c62406f4f44605dbbeddc487911845cf54 Mon Sep 17 00:00:00 2001 From: shibafu Date: Sun, 8 Nov 2020 15:38:38 +0900 Subject: [PATCH 2/4] add discard_elapsed_time option --- app/Ejaculation.php | 2 +- app/Http/Controllers/Api/WebhookController.php | 2 ++ app/Http/Controllers/EjaculationController.php | 12 ++++++++---- openapi.yaml | 6 +++++- resources/assets/js/components/CheckinForm.tsx | 18 ++++++++++++++++++ 5 files changed, 34 insertions(+), 6 deletions(-) diff --git a/app/Ejaculation.php b/app/Ejaculation.php index 4ee8b25..adc13a7 100644 --- a/app/Ejaculation.php +++ b/app/Ejaculation.php @@ -19,7 +19,7 @@ class Ejaculation extends Model protected $fillable = [ 'user_id', 'ejaculated_date', 'note', 'geo_latitude', 'geo_longitude', 'link', 'source', - 'is_private', 'is_too_sensitive', + 'is_private', 'is_too_sensitive', 'discard_elapsed_time', 'checkin_webhook_id' ]; diff --git a/app/Http/Controllers/Api/WebhookController.php b/app/Http/Controllers/Api/WebhookController.php index 0573c62..7b7fe9e 100644 --- a/app/Http/Controllers/Api/WebhookController.php +++ b/app/Http/Controllers/Api/WebhookController.php @@ -35,6 +35,7 @@ class WebhookController extends Controller 'tags.*' => ['string', 'not_regex:/[\s\r\n]/u', 'max:255'], 'is_private' => 'nullable|boolean', 'is_too_sensitive' => 'nullable|boolean', + 'discard_elapsed_time' => 'nullable|boolean', ], [ 'tags.*.not_regex' => 'The :attribute cannot contain spaces, tabs and newlines.' ]); @@ -71,6 +72,7 @@ class WebhookController extends Controller 'source' => Ejaculation::SOURCE_WEBHOOK, 'is_private' => (bool)($inputs['is_private'] ?? false), 'is_too_sensitive' => (bool)($inputs['is_too_sensitive'] ?? false), + 'discard_elapsed_time' => (bool)($inputs['discard_elapsed_time'] ?? false), 'checkin_webhook_id' => $webhook->id ]); diff --git a/app/Http/Controllers/EjaculationController.php b/app/Http/Controllers/EjaculationController.php index e062c21..d1cf236 100644 --- a/app/Http/Controllers/EjaculationController.php +++ b/app/Http/Controllers/EjaculationController.php @@ -32,7 +32,8 @@ class EjaculationController extends Controller 'note' => old('note') ?? $request->input('note', ''), 'is_private' => old('is_private') ?? $request->input('is_private', 0) == 1, 'is_too_sensitive' => old('is_too_sensitive') ?? $request->input('is_too_sensitive', 0) == 1, - 'is_realtime' => old('is_realtime', true) + 'is_realtime' => old('is_realtime', true), + 'discard_elapsed_time' => old('discard_elapsed_time') ?? $request->input('discard_elapsed_time') == 1, ], 'errors' => isset($errors) ? $errors->getMessages() : null ]; @@ -85,7 +86,8 @@ class EjaculationController extends Controller 'link' => $inputs['link'] ?? '', 'source' => Ejaculation::SOURCE_WEB, 'is_private' => $request->has('is_private') ?? false, - 'is_too_sensitive' => $request->has('is_too_sensitive') ?? false + 'is_too_sensitive' => $request->has('is_too_sensitive') ?? false, + 'discard_elapsed_time' => $request->has('discard_elapsed_time') ?? false, ]); $tagIds = []; @@ -161,7 +163,8 @@ class EjaculationController extends Controller 'tags' => $tags, 'note' => old('note') ?? $ejaculation->note, 'is_private' => is_bool(old('is_private')) ? old('is_private') : $ejaculation->is_private, - 'is_too_sensitive' => is_bool(old('is_too_sensitive')) ? old('is_too_sensitive') : $ejaculation->is_too_sensitive + 'is_too_sensitive' => is_bool(old('is_too_sensitive')) ? old('is_too_sensitive') : $ejaculation->is_too_sensitive, + 'discard_elapsed_time' => is_bool(old('discard_elapsed_time')) ? old('discard_elapsed_time') : $ejaculation->discard_elapsed_time, ], 'errors' => isset($errors) ? $errors->getMessages() : null ]; @@ -203,7 +206,8 @@ class EjaculationController extends Controller 'note' => $inputs['note'] ?? '', 'link' => $inputs['link'] ?? '', 'is_private' => $request->has('is_private') ?? false, - 'is_too_sensitive' => $request->has('is_too_sensitive') ?? false + 'is_too_sensitive' => $request->has('is_too_sensitive') ?? false, + 'discard_elapsed_time' => $request->has('discard_elapsed_time') ?? false, ])->save(); $tagIds = []; diff --git a/openapi.yaml b/openapi.yaml index 60c1560..eac0461 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -4,7 +4,7 @@ info: description: | 夜のライフログサービス Tissue の公開API仕様です。 全てのAPIのURLは `https://shikorism.net/api` から始まります。 - version: 0.1.0 + version: 0.1.1 servers: - url: 'https://shikorism.net/api' paths: @@ -51,6 +51,10 @@ paths: type: boolean default: false description: チェックイン対象のオカズをより過激なオカズとして設定 + discard_elapsed_time: + type: boolean + default: false + description: 前回チェックインからの経過時間を記録しない examples: simple: description: 何も指定しなければ、現在時刻で公開チェックインをおこないます。 diff --git a/resources/assets/js/components/CheckinForm.tsx b/resources/assets/js/components/CheckinForm.tsx index c03f1bd..7591c51 100644 --- a/resources/assets/js/components/CheckinForm.tsx +++ b/resources/assets/js/components/CheckinForm.tsx @@ -21,6 +21,7 @@ export const CheckinForm: React.FC = ({ initialState }) => { const [isRealtime, setRealtime] = useState(mode === 'create' && initialState.fields.is_realtime); const [isPrivate, setPrivate] = useState(!!initialState.fields.is_private); const [isTooSensitive, setTooSensitive] = useState(!!initialState.fields.is_too_sensitive); + const [discardElapsedTime, setDiscardElapsedTime] = useState(!!initialState.fields.discard_elapsed_time); useEffect(() => { if (mode === 'create' && isRealtime) { const id = setInterval(() => { @@ -164,6 +165,23 @@ export const CheckinForm: React.FC = ({ initialState }) => { > チェックイン対象のオカズをより過激なオカズとして設定する + setDiscardElapsedTime(v)} + > + 前回チェックインからの経過時間を記録しない +
+ + 長期間お使いにならなかった場合など、経過時間に意味が無い時のリセット用オプションです。 +
    +
  • 最長・最短記録の計算から除外されます。
  • +
  • 平均記録の起点がこのチェックインになります。
  • +
+
+
From 3825228344aaaf2b526db6a8222040992c4bdb2f Mon Sep 17 00:00:00 2001 From: shibafu Date: Sun, 8 Nov 2020 23:07:51 +0900 Subject: [PATCH 3/4] =?UTF-8?q?discard=20elapsed=20time=E3=83=95=E3=83=A9?= =?UTF-8?q?=E3=82=B0=E3=81=AE=E7=AB=8B=E3=81=A3=E3=81=9F=E3=83=81=E3=82=A7?= =?UTF-8?q?=E3=83=83=E3=82=AF=E3=82=A4=E3=83=B3=E3=81=AE=E8=A1=A8=E7=A4=BA?= =?UTF-8?q?=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Ejaculation.php | 29 +++++++++++++++++++ .../Controllers/EjaculationController.php | 16 +--------- app/Http/Controllers/UserController.php | 2 ++ resources/views/ejaculation/show.blade.php | 2 +- resources/views/user/profile.blade.php | 2 +- 5 files changed, 34 insertions(+), 17 deletions(-) diff --git a/app/Ejaculation.php b/app/Ejaculation.php index adc13a7..1ada581 100644 --- a/app/Ejaculation.php +++ b/app/Ejaculation.php @@ -105,4 +105,33 @@ class Ejaculation extends Model 'is_too_sensitive' => $this->is_too_sensitive, ]); } + + public function ejaculatedSpan(): string + { + if (array_key_exists('ejaculated_span', $this->attributes)) { + if ($this->ejaculated_span === null) { + return '精通'; + } + if ($this->discard_elapsed_time) { + return '0日 0時間 0分'; // TODO: 気の効いたフレーズにする + } + + return $this->ejaculated_span; + } else { + $previous = Ejaculation::select('ejaculated_date') + ->where('user_id', $this->user_id) + ->where('ejaculated_date', '<', $this->ejaculated_date) + ->orderByDesc('ejaculated_date') + ->first(); + + if ($previous === null) { + return '精通'; + } + if ($this->discard_elapsed_time) { + return '0日 0時間 0分'; + } + + return $this->ejaculated_date->diff($previous->ejaculated_date)->format('%a日 %h時間 %i分'); + } + } } diff --git a/app/Http/Controllers/EjaculationController.php b/app/Http/Controllers/EjaculationController.php index d1cf236..b0feb2d 100644 --- a/app/Http/Controllers/EjaculationController.php +++ b/app/Http/Controllers/EjaculationController.php @@ -121,21 +121,7 @@ class EjaculationController extends Controller ->firstOrFail(); $user = User::findOrFail($ejaculation->user_id); - // 1つ前のチェックインからの経過時間を求める - $previousEjaculation = Ejaculation::select('ejaculated_date') - ->where('user_id', $ejaculation->user_id) - ->where('ejaculated_date', '<', $ejaculation->ejaculated_date) - ->orderByDesc('ejaculated_date') - ->first(); - if (!empty($previousEjaculation)) { - $ejaculatedSpan = $ejaculation->ejaculated_date - ->diff($previousEjaculation->ejaculated_date) - ->format('%a日 %h時間 %i分'); - } else { - $ejaculatedSpan = null; - } - - return view('ejaculation.show')->with(compact('user', 'ejaculation', 'ejaculatedSpan')); + return view('ejaculation.show')->with(compact('user', 'ejaculation')); } public function edit(Request $request, $id) diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index 40b9894..81b68ea 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -35,6 +35,7 @@ is_private, is_too_sensitive, link, source, +discard_elapsed_time, to_char(before_dates.before_date, 'YYYY/MM/DD HH24:MI') AS before_date, to_char(ejaculated_date - before_dates.before_date, 'FMDDD日 FMHH24時間 FMMI分') AS ejaculated_span SQL @@ -169,6 +170,7 @@ is_private, is_too_sensitive, link, source, +discard_elapsed_time, to_char(before_dates.before_date, 'YYYY/MM/DD HH24:MI') AS before_date, to_char(ejaculated_date - before_dates.before_date, 'FMDDD日 FMHH24時間 FMMI分') AS ejaculated_span SQL diff --git a/resources/views/ejaculation/show.blade.php b/resources/views/ejaculation/show.blade.php index 9506eb1..8344480 100644 --- a/resources/views/ejaculation/show.blade.php +++ b/resources/views/ejaculation/show.blade.php @@ -31,7 +31,7 @@
-
{{ $ejaculatedSpan ?? '精通' }} {{ $ejaculation->before_date }}{{ !empty($ejaculation->before_date) ? ' ~ ' : '' }}{{ $ejaculation->ejaculated_date->format('Y/m/d H:i') }}
+
{{ $ejaculation->ejaculatedSpan() }} {{ !empty($ejaculation->before_date) && !$ejaculation->discard_elapsed_time ? $ejaculation->before_date . ' ~ ' : '' }}{{ $ejaculation->ejaculated_date->format('Y/m/d H:i') }}
@if ($ejaculation->is_private || $ejaculation->source !== 'web' || $ejaculation->tags->isNotEmpty()) diff --git a/resources/views/user/profile.blade.php b/resources/views/user/profile.blade.php index 64c2476..48ef78f 100644 --- a/resources/views/user/profile.blade.php +++ b/resources/views/user/profile.blade.php @@ -58,7 +58,7 @@
  • @if ($ejaculation->is_private || $ejaculation->source !== 'web' || $ejaculation->tags->isNotEmpty()) From 63af49ba702746e6212fac825168eb1ab682a2a2 Mon Sep 17 00:00:00 2001 From: shibafu Date: Sun, 8 Nov 2020 23:41:51 +0900 Subject: [PATCH 4/4] =?UTF-8?q?=E6=A6=82=E6=B3=81=E8=A8=88=E7=AE=97?= =?UTF-8?q?=E3=81=A7discard=20elapsed=20time=E3=82=92=E8=80=83=E6=85=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ViewComposers/ProfileStatsComposer.php | 50 ++++++++++++------- .../views/components/profile-stats.blade.php | 4 +- 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/app/Http/ViewComposers/ProfileStatsComposer.php b/app/Http/ViewComposers/ProfileStatsComposer.php index ae632a2..6521333 100644 --- a/app/Http/ViewComposers/ProfileStatsComposer.php +++ b/app/Http/ViewComposers/ProfileStatsComposer.php @@ -19,6 +19,7 @@ class ProfileStatsComposer if (!$view->offsetExists('user')) { throw new \LogicException('View data "user" was not exist.'); } + /** @var \App\User $user */ $user = $view->offsetGet('user'); // 現在のオナ禁セッションの経過時間 @@ -35,35 +36,44 @@ class ProfileStatsComposer } // 概況欄のデータ取得 - $average = DB::select(<<<'SQL' + $average = 0; + $divisor = 0; + $averageSources = DB::select(<<<'SQL' SELECT - avg(span) AS average + extract(epoch from ejaculated_date - lead(ejaculated_date, 1, NULL) OVER (ORDER BY ejaculated_date DESC)) AS span, + discard_elapsed_time FROM - ( - SELECT - extract(epoch from ejaculated_date - lead(ejaculated_date, 1, NULL) OVER (ORDER BY ejaculated_date DESC)) AS span - FROM - ejaculations - WHERE - user_id = :user_id - ORDER BY - ejaculated_date DESC - LIMIT - 30 - ) AS temp + ejaculations +WHERE + user_id = :user_id +ORDER BY + ejaculated_date DESC +LIMIT + 30 SQL , ['user_id' => $user->id]); + foreach ($averageSources as $item) { + // 経過時間記録対象外のレコードがあったら、それより古いデータは平均の計算に加えない + if ($item->discard_elapsed_time) { + break; + } + $average += $item->span; + $divisor++; + } + if ($divisor > 0) { + $average /= $divisor; + } $summary = DB::select(<<<'SQL' SELECT max(span) AS longest, min(span) AS shortest, - sum(span) AS total_times, - count(*) AS total_checkins + sum(span) AS total_times FROM ( SELECT - extract(epoch from ejaculated_date - lead(ejaculated_date, 1, NULL) OVER (ORDER BY ejaculated_date DESC)) AS span + extract(epoch from ejaculated_date - lead(ejaculated_date, 1, NULL) OVER (ORDER BY ejaculated_date DESC)) AS span, + discard_elapsed_time FROM ejaculations WHERE @@ -71,9 +81,13 @@ FROM ORDER BY ejaculated_date DESC ) AS temp +WHERE + discard_elapsed_time = FALSE SQL , ['user_id' => $user->id]); - $view->with(compact('latestEjaculation', 'currentSession', 'average', 'summary')); + $total = $user->ejaculations()->count(); + + $view->with(compact('latestEjaculation', 'currentSession', 'average', 'summary', 'total')); } } diff --git a/resources/views/components/profile-stats.blade.php b/resources/views/components/profile-stats.blade.php index 09e936c..3d3b779 100644 --- a/resources/views/components/profile-stats.blade.php +++ b/resources/views/components/profile-stats.blade.php @@ -8,8 +8,8 @@ @endif
    概況
    -

    平均記録: {{ Formatter::formatInterval($average[0]->average) }}

    +

    平均記録: {{ Formatter::formatInterval($average) }}

    最長記録: {{ Formatter::formatInterval($summary[0]->longest) }}

    最短記録: {{ Formatter::formatInterval($summary[0]->shortest) }}

    合計時間: {{ Formatter::formatInterval($summary[0]->total_times) }}

    -

    通算回数: {{ number_format($summary[0]->total_checkins) }}回

    \ No newline at end of file +

    通算回数: {{ number_format($total) }}回