From f26747c0d6e64a4ef0f5e53eb527b4e537936d72 Mon Sep 17 00:00:00 2001 From: ryo Date: Thu, 12 Dec 2024 11:13:17 +0900 Subject: [PATCH 1/3] =?UTF-8?q?=E4=B8=8D=E8=A6=81=E3=83=95=E3=82=A1?= =?UTF-8?q?=E3=82=A4=E3=83=AB=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/javascript/components/talk.vue | 50 ------------------------------ app/javascript/user-icon.vue | 26 ---------------- 2 files changed, 76 deletions(-) delete mode 100644 app/javascript/components/talk.vue delete mode 100644 app/javascript/user-icon.vue diff --git a/app/javascript/components/talk.vue b/app/javascript/components/talk.vue deleted file mode 100644 index 2005963c189..00000000000 --- a/app/javascript/components/talk.vue +++ /dev/null @@ -1,50 +0,0 @@ - - diff --git a/app/javascript/user-icon.vue b/app/javascript/user-icon.vue deleted file mode 100644 index 52fc72c58d5..00000000000 --- a/app/javascript/user-icon.vue +++ /dev/null @@ -1,26 +0,0 @@ - - - From d6990692d7ed484a66ad2009b1b24f1884800928 Mon Sep 17 00:00:00 2001 From: ryo Date: Wed, 18 Dec 2024 13:00:17 +0900 Subject: [PATCH 2/3] =?UTF-8?q?UserIcon=E3=82=92=E9=9D=9EReact=E5=8C=96?= =?UTF-8?q?=E3=81=97=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/javascript/components/Bookmarks.jsx | 26 +++++-- .../components/BookmarksInDashboard.jsx | 26 +++++-- app/javascript/components/Company.jsx | 47 +++++++------ app/javascript/components/Events.jsx | 26 +++++-- app/javascript/components/Notification.jsx | 29 +++++--- app/javascript/components/Product.jsx | 68 ++++++++++++------- app/javascript/components/RegularEvent.jsx | 38 ++++++++--- app/javascript/user-icon.js | 26 +++++++ 8 files changed, 207 insertions(+), 79 deletions(-) create mode 100644 app/javascript/user-icon.js diff --git a/app/javascript/components/Bookmarks.jsx b/app/javascript/components/Bookmarks.jsx index 50068e553f9..cd1a602a9db 100644 --- a/app/javascript/components/Bookmarks.jsx +++ b/app/javascript/components/Bookmarks.jsx @@ -1,8 +1,8 @@ -import React, { useState } from 'react' +import React, { useState, useEffect, useRef } from 'react' import useSWR, { useSWRConfig } from 'swr' import fetcher from '../fetcher' import Bootcamp from '../bootcamp' -import UserIcon from './UserIcon' +import userIcon from '../user-icon.js' import Pagination from './Pagination' import usePage from './hooks/usePage' @@ -140,6 +140,24 @@ const EditButton = ({ editable, setEditable }) => { } const Bookmark = ({ bookmark, editable, bookmarksUrl, _setEditable }) => { + // userIconの非React化により、useRef,useEffectを導入している。 + const userIconRef = useRef(null) + useEffect(() => { + const linkClass = 'card-list-item__user-link' + const imgClasses = ['card-list-item__user-icon', 'a-user-icon'] + + const userIconElement = userIcon({ + user: bookmark.user, + linkClass, + imgClasses + }) + + if (userIconRef.current) { + userIconRef.current.innerHTML = '' + userIconRef.current.appendChild(userIconElement) + } + }, [bookmark.user]) + const date = bookmark.reported_on || bookmark.created_at const createdAt = Bootcamp.iso8601ToFullTime(date) const { mutate } = useSWRConfig() @@ -157,9 +175,7 @@ const Bookmark = ({ bookmark, editable, bookmarksUrl, _setEditable }) => {
{bookmark.modelName === 'Talk' ? ( -
- -
+
) : (
{bookmark.modelNameI18n}
)} diff --git a/app/javascript/components/BookmarksInDashboard.jsx b/app/javascript/components/BookmarksInDashboard.jsx index 8b23efd7262..6e6ff1d27b2 100644 --- a/app/javascript/components/BookmarksInDashboard.jsx +++ b/app/javascript/components/BookmarksInDashboard.jsx @@ -1,8 +1,8 @@ -import React, { useState } from 'react' +import React, { useState, useEffect, useRef } from 'react' import useSWR, { useSWRConfig } from 'swr' import fetcher from '../fetcher' import Bootcamp from '../bootcamp' -import UserIcon from './UserIcon' +import userIcon from '../user-icon.js' import { toast } from '../toast_react' export default function BookmarksInDashboard() { @@ -77,6 +77,24 @@ const EditButton = ({ editable, setEditable }) => { } const Bookmark = ({ bookmark, editable, bookmarksUrl }) => { + // userIconの非React化により、useRef,useEffectを導入している。 + const userIconRef = useRef(null) + useEffect(() => { + const linkClass = 'card-list-item__user-link' + const imgClasses = ['card-list-item__user-icon', 'a-user-icon'] + + const userIconElement = userIcon({ + user: bookmark.user, + linkClass, + imgClasses + }) + + if (userIconRef.current) { + userIconRef.current.innerHTML = '' + userIconRef.current.appendChild(userIconElement) + } + }, [bookmark.user]) + const date = bookmark.reported_on || bookmark.created_at const createdAt = Bootcamp.iso8601ToFullTime(date) const { mutate } = useSWRConfig() @@ -95,9 +113,7 @@ const Bookmark = ({ bookmark, editable, bookmarksUrl }) => {
{bookmark.modelName === 'Talk' ? ( -
- -
+
) : (
{bookmark.modelNameI18n}
)} diff --git a/app/javascript/components/Company.jsx b/app/javascript/components/Company.jsx index c2b46e3b779..b98df1fdeba 100644 --- a/app/javascript/components/Company.jsx +++ b/app/javascript/components/Company.jsx @@ -1,4 +1,5 @@ -import React from 'react' +import React, { useEffect, useRef } from 'react' +import userIcon from '../user-icon.js' export default function Company({ company }) { if (company.users.length === 0) { @@ -39,28 +40,32 @@ function UserGroupHeader({ company }) { } function UserIcons({ users }) { + // userIconの非React化により、useRef,useEffectを導入している。 + const userIconRef = useRef(null) + useEffect(() => { + const linkClass = 'a-user-icons__item-link' + const imgClasses = ['a-user-icons__item-icon', 'a-user-icon'] + + const userIconElements = users.map((user) => { + return userIcon({ + user, + linkClass, + imgClasses, + loginName: user.login_name + }) + }) + + if (userIconRef.current) { + userIconRef.current.innerHTML = '' + userIconElements.forEach((element) => { + userIconRef.current.appendChild(element) + }) + } + }, [users]) + return (
-
- {users.map((user) => ( - - ))} -
+
) } - -function UserIcon({ user }) { - return ( - - - - - - ) -} diff --git a/app/javascript/components/Events.jsx b/app/javascript/components/Events.jsx index 7c8405f9fb6..f1121bda1d0 100644 --- a/app/javascript/components/Events.jsx +++ b/app/javascript/components/Events.jsx @@ -1,8 +1,8 @@ -import React from 'react' +import React, { useEffect, useRef } from 'react' import useSWR from 'swr' import Pagination from './Pagination' import LoadingListPlaceholder from './LoadingListPlaceholder' -import UserIcon from './UserIcon' +import userIcon from '../user-icon.js' import fetcher from '../fetcher' import usePage from './hooks/usePage' @@ -45,12 +45,28 @@ export default function Events() { } function Event({ event }) { + // userIconの非React化により、useRef,useEffectを導入している。 + const userIconRef = useRef(null) + useEffect(() => { + const linkClass = 'card-list-item__user-link' + const imgClasses = ['card-list-item__user-icon', 'a-user-icon'] + + const userIconElement = userIcon({ + user: event.user, + linkClass, + imgClasses + }) + + if (userIconRef.current) { + userIconRef.current.innerHTML = '' + userIconRef.current.appendChild(userIconElement) + } + }, [event.user]) + return (
  • -
    - -
    +
    diff --git a/app/javascript/components/Notification.jsx b/app/javascript/components/Notification.jsx index 61326ac5bdc..d2c53592722 100644 --- a/app/javascript/components/Notification.jsx +++ b/app/javascript/components/Notification.jsx @@ -1,10 +1,28 @@ -import React from 'react' -import UserIcon from './UserIcon' +import React, { useEffect, useRef } from 'react' +import userIcon from '../user-icon.js' import dayjs from 'dayjs' import ja from 'dayjs/locale/ja' dayjs.locale(ja) export default function Notification({ notification }) { + // userIconの非React化により、useRef,useEffectを導入している。 + const userIconRef = useRef(null) + useEffect(() => { + const linkClass = 'card-list-item__user-link' + const imgClasses = ['card-list-item__user-icon', 'a-user-icon'] + + const userIconElement = userIcon({ + user: notification.sender, + linkClass, + imgClasses + }) + + if (userIconRef.current) { + userIconRef.current.innerHTML = '' + userIconRef.current.appendChild(userIconElement) + } + }, [notification.sender]) + const createdAt = dayjs(notification.created_at).format( 'YYYY年MM月DD日(ddd) HH:mm' ) @@ -15,12 +33,7 @@ export default function Notification({ notification }) { notification.read ? 'is-read' : 'is-unread' }`}>
    -
    - -
    +
    diff --git a/app/javascript/components/Product.jsx b/app/javascript/components/Product.jsx index 4300beb9792..1e326e7d635 100644 --- a/app/javascript/components/Product.jsx +++ b/app/javascript/components/Product.jsx @@ -1,5 +1,5 @@ -import React from 'react' -import UserIcon from './UserIcon' +import React, { useEffect, useRef } from 'react' +import userIcon from '../user-icon.js' import ProductChecker from './ProductChecker' export default function Product({ @@ -9,6 +9,24 @@ export default function Product({ currentUserId, elapsedDays }) { + // userIconの非React化により、useRef,useEffectを導入している。 + const userIconRef = useRef(null) + useEffect(() => { + const linkClass = 'card-list-item__user-link' + const imgClasses = ['card-list-item__user-icon', 'a-user-icon'] + + const userIconElement = userIcon({ + user: product.user, + linkClass, + imgClasses + }) + + if (userIconRef.current) { + userIconRef.current.innerHTML = '' + userIconRef.current.appendChild(userIconElement) + } + }, [product.user]) + const notRespondedSign = () => { return ( product.self_last_commented_at_date_time > @@ -20,9 +38,7 @@ export default function Product({ return (
    -
    - -
    +
    @@ -158,25 +174,29 @@ const TimeInfo = ({ product, elapsedDays }) => { } const UserIcons = ({ users }) => { - return ( -
    - {users.map((user) => ( - - - {user.icon_title} - - - ))} -
    - ) + // userIconの非React化により、useRef,useEffectを導入している。 + const userIconRef = useRef(null) + useEffect(() => { + const linkClass = 'card-list-item__user-icons-icon' + const imgClasses = ['a-user-icon'] + + const userIconElements = users.map((user) => { + return userIcon({ + user, + linkClass, + imgClasses + }) + }) + + if (userIconRef.current) { + userIconRef.current.innerHTML = '' + userIconElements.forEach((element) => { + userIconRef.current.appendChild(element) + }) + } + }, [users]) + + return
    } const LastCommentedTime = ({ product }) => { diff --git a/app/javascript/components/RegularEvent.jsx b/app/javascript/components/RegularEvent.jsx index d8356575d24..73b1b61c9b2 100644 --- a/app/javascript/components/RegularEvent.jsx +++ b/app/javascript/components/RegularEvent.jsx @@ -1,5 +1,5 @@ -import React from 'react' -import UserIcon from './UserIcon' +import React, { useEffect, useRef } from 'react' +import userIcon from '../user-icon.js' const RegularEvent = ({ regularEvent }) => { const categoryClass = @@ -67,6 +67,28 @@ const EventTitle = ({ event }) => { } const EventOrganizers = ({ event }) => { + // userIconの非React化により、useRef,useEffectを導入している。 + const userIconRef = useRef(null) + useEffect(() => { + const linkClass = 'card-list-item__user-link' + const imgClasses = ['card-list-item__user-icon', 'a-user-icon'] + + const userIconElements = event.organizers.map((organizer) => { + return userIcon({ + user: organizer, + linkClass, + imgClasses + }) + }) + + if (userIconRef.current) { + userIconRef.current.innerHTML = '' + userIconElements.forEach((element) => { + userIconRef.current.appendChild(element) + }) + } + }, [event.organizers]) + return ( <> {event.organizers.length > 0 && ( @@ -74,15 +96,9 @@ const EventOrganizers = ({ event }) => {
    主催
    -
    - {event.organizers.map((organizer) => ( - - ))} -
    +
    diff --git a/app/javascript/user-icon.js b/app/javascript/user-icon.js new file mode 100644 index 00000000000..2f57ed3119b --- /dev/null +++ b/app/javascript/user-icon.js @@ -0,0 +1,26 @@ +export default function userIcon({ + user, + linkClass, + imgClasses, + loginName = null +}) { + const link = document.createElement('a') + link.href = user.url + link.classList.add(linkClass) + + const span = document.createElement('span') + span.classList.add('a-user-role', `is-${user.primary_role}`) + + const img = document.createElement('img') + img.src = user.avatar_url + img.alt = user.icon_title + img.title = user.icon_title + img.classList.add(...imgClasses) + if (loginName) { + img.setAttribute('data-login-name', loginName) + } + + span.appendChild(img) + link.appendChild(span) + return link +} From 67a0cdbc50f45493182ad586cca38e49dd76ee92 Mon Sep 17 00:00:00 2001 From: ryo Date: Wed, 18 Dec 2024 13:06:02 +0900 Subject: [PATCH 3/3] =?UTF-8?q?=E4=B8=8D=E8=A6=81=E3=83=95=E3=82=A1?= =?UTF-8?q?=E3=82=A4=E3=83=AB=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/javascript/components/UserIcon.jsx | 16 -------- app/javascript/components/ui/UserGroup.jsx | 46 ---------------------- 2 files changed, 62 deletions(-) delete mode 100644 app/javascript/components/UserIcon.jsx delete mode 100644 app/javascript/components/ui/UserGroup.jsx diff --git a/app/javascript/components/UserIcon.jsx b/app/javascript/components/UserIcon.jsx deleted file mode 100644 index 14786fcfde1..00000000000 --- a/app/javascript/components/UserIcon.jsx +++ /dev/null @@ -1,16 +0,0 @@ -import React from 'react' - -export default function UserIcon({ user, blockClassSuffix }) { - return ( - - - {user.icon_title} - - - ) -} diff --git a/app/javascript/components/ui/UserGroup.jsx b/app/javascript/components/ui/UserGroup.jsx deleted file mode 100644 index cc86d9687eb..00000000000 --- a/app/javascript/components/ui/UserGroup.jsx +++ /dev/null @@ -1,46 +0,0 @@ -import React from 'react' -import clsx from 'clsx' - -export const UserGroup = ({ className, ...props }) => { - return
    -} - -const UserGroupHeader = ({ className, children, ...props }) => { - return ( -
    -

    {children}

    -
    - ) -} - -const UserGroupIcons = ({ users, className, ...props }) => { - return ( -
    -
    - {users.map((user) => ( - - ))} -
    -
    - ) -} - -const UserIcon = ({ user }) => { - const primaryRole = `is-${user.primary_role}` - - return ( - - - - - - ) -} - -UserGroup.Header = UserGroupHeader -UserGroup.Icons = UserGroupIcons