fix post-page rkey

This commit is contained in:
2025-06-15 21:15:35 +09:00
parent d4d98e2e91
commit 619675b551
6 changed files with 38 additions and 58 deletions

Binary file not shown.

View File

@ -1,3 +1,3 @@
<!-- OAuth Comment System - Load globally for session management --> <!-- OAuth Comment System - Load globally for session management -->
<script type="module" crossorigin src="/assets/comment-atproto-C3utAhPv.js"></script> <script type="module" crossorigin src="/assets/comment-atproto-C2nhj09r.js"></script>
<link rel="stylesheet" crossorigin href="/assets/comment-atproto-BH-72ESb.css"> <link rel="stylesheet" crossorigin href="/assets/comment-atproto-6vwaM28e.css">

View File

@ -1,3 +1,3 @@
<!-- OAuth Comment System - Load globally for session management --> <!-- OAuth Comment System - Load globally for session management -->
<script type="module" crossorigin src="/assets/comment-atproto-C3utAhPv.js"></script> <script type="module" crossorigin src="/assets/comment-atproto-C2nhj09r.js"></script>
<link rel="stylesheet" crossorigin href="/assets/comment-atproto-BH-72ESb.css"> <link rel="stylesheet" crossorigin href="/assets/comment-atproto-6vwaM28e.css">

View File

@ -499,9 +499,8 @@
} }
.comments-list { .comments-list {
border: 1px solid #ddd;
border-radius: 8px; border-radius: 8px;
padding: 20px; padding: 0px;
} }
.comments-header { .comments-header {
@ -860,28 +859,6 @@
background: #f6f8fa; background: #f6f8fa;
} }
/* AI Chat History */
.ai-chat-list {
max-width: 100%;
border: 1px solid #ddd;
border-radius: 8px;
padding: 20px;
}
.chat-item {
border: 1px solid #d1d9e0;
border-radius: 8px;
padding: 16px;
margin-bottom: 16px;
background: #ffffff;
}
.chat-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 12px;
}
.chat-actions { .chat-actions {
display: flex; display: flex;

View File

@ -259,8 +259,8 @@ function App() {
if (appConfig.rkey) { if (appConfig.rkey) {
// On post page: show only chats for this specific post // On post page: show only chats for this specific post
filteredRecords = allChatRecords.filter(record => { filteredRecords = allChatRecords.filter(record => {
const recordPath = record.value.post?.url ? new URL(record.value.post.url).pathname : ''; const recordRkey = record.value.post?.url ? new URL(record.value.post.url).pathname.split('/').pop()?.replace(/\.html$/, '') : '';
return recordPath === window.location.pathname; return recordRkey === appConfig.rkey;
}); });
} else { } else {
// On top page: show latest 3 records from all pages // On top page: show latest 3 records from all pages
@ -302,13 +302,12 @@ function App() {
const langData = await langResponse.json(); const langData = await langResponse.json();
const langRecords = langData.records || []; const langRecords = langData.records || [];
// Filter by current page path if on post page // Filter by current page rkey if on post page
const filteredLangRecords = appConfig.rkey const filteredLangRecords = appConfig.rkey
? langRecords.filter(record => { ? langRecords.filter(record => {
// Compare path only, not full URL to support localhost vs production // Compare rkey only (last part of path)
const recordPath = record.value.post?.url ? new URL(record.value.post.url).pathname : const recordRkey = record.value.post?.url ? new URL(record.value.post.url).pathname.split('/').pop()?.replace(/\.html$/, '') : '';
record.value.url ? new URL(record.value.url).pathname : ''; return recordRkey === appConfig.rkey;
return recordPath === window.location.pathname;
}) })
: langRecords.slice(0, 3); // Top page: latest 3 : langRecords.slice(0, 3); // Top page: latest 3
@ -321,13 +320,12 @@ function App() {
const commentData = await commentResponse.json(); const commentData = await commentResponse.json();
const commentRecords = commentData.records || []; const commentRecords = commentData.records || [];
// Filter by current page path if on post page // Filter by current page rkey if on post page
const filteredCommentRecords = appConfig.rkey const filteredCommentRecords = appConfig.rkey
? commentRecords.filter(record => { ? commentRecords.filter(record => {
// Compare path only, not full URL to support localhost vs production // Compare rkey only (last part of path)
const recordPath = record.value.post?.url ? new URL(record.value.post.url).pathname : const recordRkey = record.value.post?.url ? new URL(record.value.post.url).pathname.split('/').pop()?.replace(/\.html$/, '') : '';
record.value.url ? new URL(record.value.url).pathname : ''; return recordRkey === appConfig.rkey;
return recordPath === window.location.pathname;
}) })
: commentRecords.slice(0, 3); // Top page: latest 3 : commentRecords.slice(0, 3); // Top page: latest 3
@ -540,16 +538,14 @@ function App() {
// ページpathでフィルタリング指定された場合 // ページpathでフィルタリング指定された場合
const filteredComments = pageUrl const filteredComments = pageUrl && appConfig.rkey
? userComments.filter(record => { ? userComments.filter(record => {
try { try {
// Compare path only, not full URL to support localhost vs production // Compare rkey only (last part of path)
const recordPath = record.value.url ? new URL(record.value.url).pathname : ''; const recordRkey = record.value.url ? new URL(record.value.url).pathname.split('/').pop() : '';
const currentPath = new URL(pageUrl).pathname; return recordRkey === appConfig.rkey;
return recordPath === currentPath;
} catch (err) { } catch (err) {
// Fallback to exact match if URL parsing fails return false;
return record.value.url === pageUrl;
} }
}) })
: userComments; : userComments;
@ -1053,6 +1049,8 @@ function App() {
<div className="username-input-section"> <div className="username-input-section">
<input <input
type="text" type="text"
id="handle-input"
name="handle"
placeholder="user.bsky.social" placeholder="user.bsky.social"
className="handle-input" className="handle-input"
value={handleInput} value={handleInput}
@ -1094,6 +1092,8 @@ function App() {
{/* User List Form */} {/* User List Form */}
<div className="user-list-form"> <div className="user-list-form">
<textarea <textarea
id="user-list-input"
name="userList"
value={userListInput} value={userListInput}
onChange={(e) => setUserListInput(e.target.value)} onChange={(e) => setUserListInput(e.target.value)}
placeholder="ユーザーハンドルをカンマ区切りで入力&#10;例: syui.ai, yui.syui.ai, user.bsky.social" placeholder="ユーザーハンドルをカンマ区切りで入力&#10;例: syui.ai, yui.syui.ai, user.bsky.social"
@ -1188,13 +1188,13 @@ function App() {
className={`tab-button ${activeTab === 'ai-chat' ? 'active' : ''}`} className={`tab-button ${activeTab === 'ai-chat' ? 'active' : ''}`}
onClick={() => setActiveTab('ai-chat')} onClick={() => setActiveTab('ai-chat')}
> >
AI Chat History ({aiChatHistory.length}) AI Chat ({aiChatHistory.length})
</button> </button>
<button <button
className={`tab-button ${activeTab === 'lang-en' ? 'active' : ''}`} className={`tab-button ${activeTab === 'lang-en' ? 'active' : ''}`}
onClick={() => setActiveTab('lang-en')} onClick={() => setActiveTab('lang-en')}
> >
Lang: EN ({langEnRecords.length}) AI Lang:en ({langEnRecords.length})
</button> </button>
<button <button
className={`tab-button ${activeTab === 'ai-comment' ? 'active' : ''}`} className={`tab-button ${activeTab === 'ai-comment' ? 'active' : ''}`}
@ -1304,10 +1304,7 @@ function App() {
{/* AI Chat History List */} {/* AI Chat History List */}
{activeTab === 'ai-chat' && ( {activeTab === 'ai-chat' && (
<div className="ai-chat-list"> <div className="comments-list">
<div className="chat-header">
<h3>AI Chat History</h3>
</div>
{aiChatHistory.length === 0 ? ( {aiChatHistory.length === 0 ? (
<p className="no-chat">No AI conversations yet. Start chatting with Ask AI!</p> <p className="no-chat">No AI conversations yet. Start chatting with Ask AI!</p>
) : ( ) : (
@ -1319,8 +1316,8 @@ function App() {
const displayName = isAiResponse ? 'AI' : (record.value.author?.displayName || record.value.author?.handle); const displayName = isAiResponse ? 'AI' : (record.value.author?.displayName || record.value.author?.handle);
return ( return (
<div key={index} className="chat-item"> <div key={index} className="comment-item">
<div className="chat-header"> <div className="comment-header">
<img <img
src={generatePlaceholderAvatar(displayHandle || 'unknown')} src={generatePlaceholderAvatar(displayHandle || 'unknown')}
alt={isAiResponse ? "AI Avatar" : "User Avatar"} alt={isAiResponse ? "AI Avatar" : "User Avatar"}
@ -1404,7 +1401,7 @@ function App() {
{/* Lang: EN List */} {/* Lang: EN List */}
{activeTab === 'lang-en' && ( {activeTab === 'lang-en' && (
<div className="lang-en-list"> <div className="comments-list">
{langEnRecords.length === 0 ? ( {langEnRecords.length === 0 ? (
<p className="no-content">No English translations yet</p> <p className="no-content">No English translations yet</p>
) : ( ) : (
@ -1501,6 +1498,8 @@ function App() {
<div className="comment-form"> <div className="comment-form">
<h3>Post a Comment</h3> <h3>Post a Comment</h3>
<textarea <textarea
id="comment-text"
name="commentText"
value={commentText} value={commentText}
onChange={(e) => setCommentText(e.target.value)} onChange={(e) => setCommentText(e.target.value)}
placeholder="Write your comment..." placeholder="Write your comment..."

View File

@ -62,11 +62,15 @@ function generateBaseCollectionFromHost(host: string): string {
} }
// Extract rkey from current URL // Extract rkey from current URL
// /posts/xxx -> xxx // /posts/xxx -> xxx (remove .html if present)
function extractRkeyFromUrl(): string | undefined { function extractRkeyFromUrl(): string | undefined {
const pathname = window.location.pathname; const pathname = window.location.pathname;
const match = pathname.match(/\/posts\/([^/]+)\/?$/); const match = pathname.match(/\/posts\/([^/]+)\/?$/);
return match ? match[1] : undefined; if (match) {
// Remove .html extension if present
return match[1].replace(/\.html$/, '');
}
return undefined;
} }
// Get application configuration from environment variables // Get application configuration from environment variables