Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enhance: 「今日誕生日のユーザー」→「もうすぐ誕生日のユーザー」 #13637

Open
wants to merge 31 commits into
base: develop
Choose a base branch
from

Conversation

kakkokari-gtyih
Copy link
Contributor

@kakkokari-gtyih kakkokari-gtyih commented Mar 30, 2024

What

Cherry-picked from MisskeyIO@24652b9 MisskeyIO@3858100 MisskeyIO@fa47a54

  • 「今日誕生日のユーザー」を「もうすぐ誕生日のユーザー」に名称変更
  • 今日だけに限らず、直近の誕生日ユーザーを表示できるように
  • その場でメンションしてノートできるように

ioからの変更点

  • 名称を「もうすぐ誕生日のユーザー」に統一
  • 日付が1ヶ月ずれる場合があるのを別の方法で修正
  • バックエンドとフロントエンドのタイムゾーンが違う場合に対応

見た目・仕組みはMisskey.ioで稼働しているものからほぼ変更なし

Why

そのほうが圧倒的に便利

Additional info (optional)

users/followingbirthday パラメータは削除した

Checklist

  • Read the contribution guide
  • Test working in a local environment
  • (If needed) Add story of storybook
  • (If needed) Update CHANGELOG.md
  • (If possible) Add tests

@github-actions github-actions bot added packages/frontend Client side specific issue/PR packages/backend Server side specific issue/PR packages/misskey-js labels Mar 30, 2024
Copy link

codecov bot commented Mar 30, 2024

Codecov Report

Attention: Patch coverage is 59.69388% with 79 lines in your changes missing coverage. Please review.

Project coverage is 66.60%. Comparing base (b269c43) to head (9c3c5dc).

Files Patch % Lines
...pi/endpoints/users/get-following-birthday-users.ts 53.89% 71 Missing ⚠️
...ackend/src/server/api/endpoints/users/following.ts 36.36% 7 Missing ⚠️
...ges/backend/src/server/api/endpoints/users/show.ts 92.30% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##           develop   #13637       +/-   ##
============================================
- Coverage    77.90%   66.60%   -11.31%     
============================================
  Files          185     1008      +823     
  Lines        25563   120115    +94552     
  Branches       487     4631     +4144     
============================================
+ Hits         19916    79997    +60081     
- Misses        5640    40091    +34451     
- Partials         7       27       +20     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Contributor

github-actions bot commented Mar 30, 2024

このPRによるapi.jsonの差分

差分はこちら
--- base
+++ head
@@ -68051,7 +68051,8 @@
                       "string",
                       "null"
                     ],
-                    "pattern": "^([0-9]{4})-([0-9]{2})-([0-9]{2})$"
+                    "pattern": "^([0-9]{4})-([0-9]{2})-([0-9]{2})$",
+                    "description": "@deprecated use get-following-birthday-users instead."
                   }
                 },
                 "anyOf": [
@@ -68389,6 +68390,250 @@
         }
       }
     },
+    "/users/get-following-birthday-users": {
+      "post": {
+        "operationId": "users___get-following-birthday-users",
+        "summary": "users/get-following-birthday-users",
+        "description": "Find users who have a birthday on the specified range.\n\n**Credential required**: *Yes* / **Permission**: *read:account*",
+        "externalDocs": {
+          "description": "Source code",
+          "url": "https://github.com/misskey-dev/misskey/blob/develop/packages/backend/src/server/api/endpoints/users/get-following-birthday-users.ts"
+        },
+        "tags": [
+          "users"
+        ],
+        "security": [
+          {
+            "bearerAuth": []
+          }
+        ],
+        "requestBody": {
+          "required": true,
+          "content": {
+            "application/json": {
+              "schema": {
+                "type": "object",
+                "properties": {
+                  "limit": {
+                    "type": "integer",
+                    "minimum": 1,
+                    "maximum": 100,
+                    "default": 10
+                  },
+                  "offset": {
+                    "type": "integer",
+                    "default": 0
+                  },
+                  "birthday": {
+                    "type": "object",
+                    "properties": {
+                      "month": {
+                        "type": "integer",
+                        "minimum": 1,
+                        "maximum": 12
+                      },
+                      "day": {
+                        "type": "integer",
+                        "minimum": 1,
+                        "maximum": 31
+                      },
+                      "begin": {
+                        "type": "object",
+                        "properties": {
+                          "month": {
+                            "type": "integer",
+                            "minimum": 1,
+                            "maximum": 12
+                          },
+                          "day": {
+                            "type": "integer",
+                            "minimum": 1,
+                            "maximum": 31
+                          }
+                        },
+                        "required": [
+                          "month",
+                          "day"
+                        ]
+                      },
+                      "end": {
+                        "type": "object",
+                        "properties": {
+                          "month": {
+                            "type": "integer",
+                            "minimum": 1,
+                            "maximum": 12
+                          },
+                          "day": {
+                            "type": "integer",
+                            "minimum": 1,
+                            "maximum": 31
+                          }
+                        },
+                        "required": [
+                          "month",
+                          "day"
+                        ]
+                      }
+                    },
+                    "anyOf": [
+                      {
+                        "required": [
+                          "month",
+                          "day"
+                        ]
+                      },
+                      {
+                        "required": [
+                          "begin",
+                          "end"
+                        ]
+                      }
+                    ]
+                  }
+                },
+                "required": [
+                  "birthday"
+                ]
+              }
+            }
+          }
+        },
+        "responses": {
+          "200": {
+            "description": "OK (with results)",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "type": "array",
+                  "items": {
+                    "type": "object",
+                    "properties": {
+                      "birthday": {
+                        "type": "string"
+                      },
+                      "user": {
+                        "type": "object",
+                        "$ref": "#/components/schemas/UserLite"
+                      }
+                    },
+                    "required": [
+                      "birthday",
+                      "user"
+                    ]
+                  }
+                }
+              }
+            }
+          },
+          "400": {
+            "description": "Client error",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/Error"
+                },
+                "examples": {
+                  "INVALID_PARAM": {
+                    "value": {
+                      "error": {
+                        "message": "Invalid param.",
+                        "code": "INVALID_PARAM",
+                        "id": "3d81ceae-475f-4600-b2a8-2bc116157532"
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          },
+          "401": {
+            "description": "Authentication error",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/Error"
+                },
+                "examples": {
+                  "CREDENTIAL_REQUIRED": {
+                    "value": {
+                      "error": {
+                        "message": "Credential required.",
+                        "code": "CREDENTIAL_REQUIRED",
+                        "id": "1384574d-a912-4b81-8601-c7b1c4085df1"
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          },
+          "403": {
+            "description": "Forbidden error",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/Error"
+                },
+                "examples": {
+                  "AUTHENTICATION_FAILED": {
+                    "value": {
+                      "error": {
+                        "message": "Authentication failed. Please ensure your token is correct.",
+                        "code": "AUTHENTICATION_FAILED",
+                        "id": "b0a7f5f8-dc2f-4171-b91f-de88ad238e14"
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          },
+          "418": {
+            "description": "I'm Ai",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/Error"
+                },
+                "examples": {
+                  "I_AM_AI": {
+                    "value": {
+                      "error": {
+                        "message": "You sent a request to Ai-chan, Misskey's showgirl, instead of the server.",
+                        "code": "I_AM_AI",
+                        "id": "60c46cd1-f23a-46b1-bebe-5d2b73951a84"
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Internal server error",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/Error"
+                },
+                "examples": {
+                  "INTERNAL_ERROR": {
+                    "value": {
+                      "error": {
+                        "message": "Internal error occurred. Please contact us if the error persists.",
+                        "code": "INTERNAL_ERROR",
+                        "id": "5d37dbcb-891e-41ca-a3d6-e690c97775ac"
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    },
     "/users/get-frequently-replied-users": {
       "post": {
         "operationId": "users___get-frequently-replied-users",
@@ -72774,6 +73019,10 @@
                       "null"
                     ],
                     "description": "The local host is represented with `null`."
+                  },
+                  "detailed": {
+                    "type": "boolean",
+                    "default": true
                   }
                 },
                 "anyOf": [
@@ -72806,10 +73055,21 @@
                   "oneOf": [
                     {
                       "type": "object",
+                      "$ref": "#/components/schemas/UserLite"
+                    },
+                    {
+                      "type": "object",
                       "$ref": "#/components/schemas/UserDetailed"
                     },
                     {
                       "type": "array",
+                      "items": {
+                        "type": "object",
+                        "$ref": "#/components/schemas/UserLite"
+                      }
+                    },
+                    {
+                      "type": "array",
                       "items": {
                         "type": "object",
                         "$ref": "#/components/schemas/UserDetailed"

Get diff files from Workflow Page

@kakkokari-gtyih kakkokari-gtyih changed the title enhance: 「もうすぐ誕生日のユーザー」ウィジェットにする enhance: 「今日誕生日のユーザー」→「もうすぐ誕生日のユーザー」 Mar 30, 2024
@kakkokari-gtyih

This comment was marked as resolved.

@kakkokari-gtyih kakkokari-gtyih marked this pull request as draft March 30, 2024 12:12
@kakkokari-gtyih kakkokari-gtyih marked this pull request as ready for review March 31, 2024 01:55
@kakkokari-gtyih kakkokari-gtyih marked this pull request as draft March 31, 2024 01:58
@kakkokari-gtyih
Copy link
Contributor Author

ちがった
MkDateSeparatedListの表示がなんかおかしい?

@kakkokari-gtyih
Copy link
Contributor Author

API側で出力される誕生日の月が1ヶ月おかしいかも

@kakkokari-gtyih
Copy link
Contributor Author

kakkokari-gtyih commented Mar 31, 2024

javascriptのバグ踏んだ? → なおった

↓ これなら動く

// item.birthday_date = 401;

const birthday = new Date();
const monthForDate = Math.floor(item.birthday_date / 100) - 1; // 3
birthday.setMonth(monthForDate, item.birthday_date % 100);
birthday.setHours(0, 0, 0, 0);
if (birthday.getTime() < Date.now()) birthday.setFullYear(new Date().getFullYear() + 1);

const bdayString = birthday.toISOString();
// bdayString = '2024-04-01T15:00:00.000Z' ← OK

↓ こうするとおかしくなる(もとの実装)

// item.birthday_date = 401;

const birthday = new Date();
const monthForDate = Math.floor(item.birthday_date / 100) - 1; // 3
birthday.setMonth(monthForDate);
birthday.setDate(item.birthday_date % 100);
birthday.setHours(0, 0, 0, 0);
if (birthday.getTime() < Date.now()) birthday.setFullYear(new Date().getFullYear() + 1);

const bdayString = birthday.toISOString();
// bdayString = '2024-05-01T15:00:00.000Z' ← おかしい

@acid-chicken
Copy link
Member

javascriptのバグ踏んだ?

(主観的にどうというのは抜きにして)言語仕様のバグではないけど……

const birthday = new Date(); この時点では今日は 3/31
const monthForDate = Math.floor(item.birthday_date / 100) - 1; // 3
birthday.setMonth(monthForDate); この時点で 3/31 の月を 4 にしようとする → 4/31 などという日付はないので正規化して 5/1 になる
birthday.setDate(item.birthday_date % 100); 5/1 の日付を 1 にしようとする → 5/1

@kakkokari-gtyih
Copy link
Contributor Author

kakkokari-gtyih commented Mar 31, 2024

5d41ee3 で、

  • 定数dateが今日であれば今日を返す (2024-03-31)
  • 定数dateが明日以降であれば今年の日付を返す (2024-12-01)
  • 定数dateが昨日以前であれば来年の日付を返す (2025-01-01)
  • Dateコンストラクタの仕様で、閏日2/29は3/1として扱われる

という仕様になった(この問題は解消されたはず)

※マジでバグだと思っていたが実装のやり方がまずかっただけらしいことが後でわかった

@taiyme
Copy link
Contributor

taiyme commented Mar 31, 2024

月末だけ発生する問題なので、いま発見できて良かった

@kakkokari-gtyih kakkokari-gtyih marked this pull request as ready for review March 31, 2024 08:15
@kakkokari-gtyih
Copy link
Contributor Author

kakkokari-gtyih commented Apr 4, 2024

これ今日の誕生日の人がちゃんと区別つくように今日の人だけデコってもいいかもね
こういう感じ?(既存のアイコンデコレーションとダブりそうなので背景色変更だけでもいい可能性はあるけど)

image

@kakkokari-gtyih
Copy link
Contributor Author

これ今日の誕生日の人がちゃんと区別つくように今日の人だけデコってもいいかもね こういう感じ?(既存のアイコンデコレーションとダブりそうなので背景色変更だけでもいい可能性はあるけど)

フロントエンドいじるだけで対応できそうなので今決められなければ後でやっても問題なさそう

@kakkokari-gtyih
Copy link
Contributor Author

コンフリクト解消

@kleuzjatob

This comment was marked as off-topic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
packages/backend Server side specific issue/PR packages/frontend Client side specific issue/PR packages/misskey-js
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants