-
Notifications
You must be signed in to change notification settings - Fork 75
Bookmarks.jsxを非React化する #9181
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
Bookmarks.jsxを非React化する #9181
Changes from all commits
96aba17
7afa975
2fd21e1
c3c5e8d
15a753e
5ede14e
86a09d1
bc73f0c
f1e0b82
c72f92b
a1087a0
acaa488
f1f58e2
857481b
ca411ec
d75047e
5ce49bb
574b74e
e2e769c
611e8a9
2be8774
31525e0
84c32e9
57d8590
5466235
f87191a
485360d
8323a60
82c8adb
be84b10
e5c847a
2dc4182
f36b854
0259b06
1fb26ab
45ab3bf
f138a9d
6478092
3e36df6
a9c5757
f5ecbac
2cec738
20780f4
be42876
25cbf94
b24fb2f
c48ac75
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,20 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| class CurrentUser::BookmarksController < ApplicationController | ||
| def index | ||
| @user = current_user | ||
| PAGER_NUMBER = 20 | ||
|
|
||
| before_action :set_bookmarks, only: [:index] | ||
|
|
||
| def index; end | ||
|
|
||
| def destroy | ||
| current_user.bookmarks.find(params[:id]).destroy | ||
| head :no_content | ||
| end | ||
|
|
||
| private | ||
|
|
||
| def set_bookmarks | ||
| @bookmarks = current_user.bookmarks.preload(bookmarkable: :user).order(created_at: :desc, id: :desc).page(params[:page]).per(PAGER_NUMBER) | ||
| end | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| end | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| export function toggleDeleteButtonVisibility(editToggle, deleteButtons) { | ||
| const displayStyle = editToggle.checked ? 'block' : 'none' | ||
| for (const button of deleteButtons) { | ||
| button.style.display = displayStyle | ||
| } | ||
| } |
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| import { get, destroy } from '@rails/request.js' | ||
| import { toggleDeleteButtonVisibility } from './bookmarks-delete-button-visibility' | ||
|
|
||
| const EDIT_MODE_KEY = 'bookmark_edit_mode' | ||
| const DELETE_BUTTON_CLASS = 'js-bookmark-delete-button' | ||
|
|
||
| document.addEventListener('DOMContentLoaded', () => { | ||
| const editButton = document.getElementById('bookmark_edit') | ||
| const pageBody = document.querySelector('.page-body') | ||
| if (!pageBody) return | ||
|
|
||
| const savedValue = sessionStorage.getItem(EDIT_MODE_KEY) | ||
| const savedMode = savedValue === 'true' | ||
| initialize(savedMode) | ||
|
|
||
| if (editButton) { | ||
| editButton.addEventListener('change', () => { | ||
| const deleteButtons = document.getElementsByClassName(DELETE_BUTTON_CLASS) | ||
| toggleDeleteButtonVisibility(editButton, deleteButtons) | ||
| sessionStorage.setItem(EDIT_MODE_KEY, editButton.checked) | ||
| }) | ||
| } | ||
|
|
||
| document.addEventListener('click', async (event) => { | ||
| const deleteButton = event.target.closest('.bookmark-delete-button') | ||
| if (!deleteButton) return | ||
|
|
||
| deleteButton.disabled = true | ||
|
|
||
| try { | ||
| const url = deleteButton.dataset.url | ||
| const response = await destroy(url) | ||
|
|
||
| if (!response.ok) { | ||
| throw new Error(`削除に失敗しました。(ステータス: ${response.status})`) | ||
| } | ||
|
|
||
| const params = new URLSearchParams(location.search) | ||
| const currentPage = parseInt(params.get('page') || '1', 10) | ||
| const newPageMain = await fetchPageMain(currentPage) | ||
|
|
||
| // 空ページの場合は1ページ前にフォールバック | ||
| let pageToShow = newPageMain | ||
| if (currentPage > 1 && newPageMain.querySelector('.o-empty-message')) { | ||
| pageToShow = await fetchPageMain(currentPage - 1) | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. バグに気づいていただいてありがとうございます🙏 kaminariの空ページ問題とその対処について初めて知りました💡 このままでもよいと思いますが、空ページのフォールバックであることがわかるようなメソッド名をつけてロジックをそのまま切り出したり、もしくはコメントを一言添えるだけでもより読みやすくなると思いました。 const pageToShow = await メソッド()
document.querySelector('.page-body').replaceWith(pageToShow)
const fetchPageMain = async (page) => {
}
const メソッド = async () => {
// fetchPageMainはこの中で呼び出す(デコレーターパターン)
}
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. フォールバックという単語をはじめて知りました👀 こちらでコメントをつける修正をしました。
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 私もはじめて使ったかもしれません! コメント追加ありがとうございます🙏 |
||
| document.querySelector('.page-body').replaceWith(pageToShow) | ||
|
|
||
| const savedModeAfterDelete = | ||
| sessionStorage.getItem(EDIT_MODE_KEY) === 'true' | ||
| initialize(savedModeAfterDelete) | ||
| } catch (error) { | ||
| console.warn(error) | ||
| deleteButton.disabled = false | ||
| } | ||
| }) | ||
| }) | ||
|
|
||
| window.addEventListener('beforeunload', () => { | ||
| const isBookmarkPage = location.pathname.includes('/current_user/bookmarks') | ||
| if (!isBookmarkPage) { | ||
| sessionStorage.removeItem(EDIT_MODE_KEY) | ||
| } | ||
| }) | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 特定の要素とかではなくpathで判定するのは確実だしわかりやすいですね!👍 |
||
| const fetchPageMain = async (page) => { | ||
| const bookmarkUrl = `/current_user/bookmarks?page=${page}` | ||
| const response = await get(bookmarkUrl, { responseKind: 'html' }) | ||
| const html = await response.text | ||
| const parser = new DOMParser() | ||
| const parsedDocument = parser.parseFromString(html, 'text/html') | ||
| return parsedDocument.querySelector('.page-body') | ||
| } | ||
|
|
||
| const initialize = (deleteMode = false) => { | ||
| const editButton = document.getElementById('bookmark_edit') | ||
| const deleteButtons = document.getElementsByClassName(DELETE_BUTTON_CLASS) | ||
|
|
||
| if (editButton && deleteButtons.length > 0) { | ||
| editButton.checked = deleteMode | ||
| toggleDeleteButtonVisibility(editButton, deleteButtons) | ||
| } | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. initializerの設置ありがとうございます🙏 次の2点が気になりました。
DOMContentLoaded () {
// ここで編集ボタンを取得・イベントリスナー設定
function initializer() {
// クロージャで編集ボタンにアクセス
}
function handleEditToggleChange() {
// クロージャで編集ボタンにアクセス
}
initializer() // 初回実行
}
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 教えてくださり、ありがとうございます!
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 修正ありがとうございます!
いいえ!💦 私も確証が持てないままベストエフォートでコメントしている感じなので、自分がこう書きたいということがあればぜひ遠慮なく言ってください👍 |
||
This file was deleted.
Uh oh!
There was an error while loading. Please reload this page.