Skip to content

Conversation

@timerring
Copy link
Member

Summary

Add support for Jianshu (简书) platform in the COSE browser extension, enabling users to sync articles directly to Jianshu. This update includes a new modular platform configuration, API-based login detection with real user profile retrieval, proper note creation workflow with notebook selection, and native textarea-based content filling.

Changes

Browser Extension (cose/)

Platform Configuration:

  • Added Jianshu to the platform registry with official favicon.
  • Created new src/platforms/jianshu.js to encapsulate all Jianshu-specific logic (platform config, login detection, content filler).
  • Integrated Jianshu into src/platforms/index.js for centralized platform management.
  • Added Jianshu domain permissions (https://*.jianshu.com/*) to manifest.json.

Login Detection:

  • Implemented API-based authentication using GET https://www.jianshu.com/author/current_user.
  • Retrieves real user profile data including:
    • nickname: Actual username
    • avatar: User avatar URL
    • id: Unique user identifier
  • Returns { loggedIn: true, username, avatar } when authenticated.
  • Gracefully handles unauthenticated state by returning { loggedIn: false }.

Note Creation Workflow:

  • Critical Fix: Jianshu requires a valid notebook and note ID in URL for editor initialization. Direct access to /writer without proper note context causes editor failure.
  • Implemented proper workflow in syncToPlatform():
    1. Call GET https://www.jianshu.com/author/notebooks to fetch user's notebook list
    2. Select the first available notebook (with validation for empty notebook list)
    3. Call POST https://www.jianshu.com/author/notes to create a new note with notebook_id and initial title
    4. Extract note ID from response: {"id": 123456789}
    5. Navigate to correct URL: https://www.jianshu.com/writer#/notebooks/{notebookId}/notes/{noteId}
  • Added error handling for API failures with user-friendly messages.

Content Filler:

  • Created fillJianshuContent() supporting Jianshu's native Markdown editor.
  • Technical Challenge Solved: Jianshu uses React-controlled inputs that don't respond to simple value assignment.
  • Solution: Use native property descriptor setter to bypass React's synthetic event system.
  • Content Filling Method:
    • Title: Target input._24i7u or input[class*="title"], use HTMLInputElement.prototype.value setter
    • Content: Target #arthur-editor or textarea._3swFR, use HTMLTextAreaElement.prototype.value setter
    • Dispatch proper events (input, change, blur) to trigger React state updates
  • Why Native Setter: Direct element.value = x assignment doesn't trigger React's controlled component updates. Using the native setter with proper event dispatching ensures the editor recognizes the content change.

Web Application (apps/web/)

Login URL Integration:

  • Added Jianshu login URL (https://www.jianshu.com/sign_in) to PostInfo.vue for the "Login" link functionality.
  • Added Jianshu platform entry to inject.js for frontend display.

Technical Details

Notebook-Based Architecture:

  • Jianshu organizes articles within "notebooks" (文集). Users must have at least one notebook to create articles.
  • The extension automatically selects the first notebook for new article creation.
  • If no notebooks exist, displays error message: "简书未找到文集,请先创建一个文集".

React Controlled Input Handling:

  • Jianshu's editor uses React controlled components where the component state controls the input value.
  • Standard DOM manipulation (element.value = x) doesn't work because React doesn't detect the change.
  • Solution: Access the native setter via Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set and call it directly, then dispatch synthetic events to notify React.

Editor Selectors:

  • Title input: input._24i7u (primary) or input[class*="title"] (fallback)
  • Content editor: #arthur-editor (primary) or textarea._3swFR (fallback)
  • These class names are minified and may change; fallback selectors provide resilience.

Modular Architecture:

  • Following the pattern established for other platforms, all Jianshu logic is self-contained in jianshu.js.
  • Separates concerns: platform config, login detection, and content filling.
  • Makes future maintenance and updates straightforward.

Testing

  1. Install/Reload the COSE extension.

Logged-Out Test:

  • Ensure you are logged out of Jianshu (https://www.jianshu.com/).
  • Open the Markdown editor publish dialog.
  • Verify Jianshu shows a "登录" (Login) link.
  • Click the login link and confirm it navigates to the Jianshu login page.

Logged-In Test:

  • Log in to Jianshu in the browser.
  • Reopen the publish dialog.
  • Verify Jianshu shows the correct username and avatar image.
  • Confirm logged-in status is displayed.

Sync Test:

  • Ensure you have at least one notebook (文集) in your Jianshu account.
  • Select Jianshu and click "确定" (Confirm) to sync.
  • Confirm the extension creates a new note and opens https://www.jianshu.com/writer#/notebooks/{notebookId}/notes/{noteId}.
  • Wait for editor initialization (should complete within 1-2 seconds).
  • Confirm the Title is correctly populated in the title input field.
  • Confirm the Markdown Content is correctly filled in the textarea editor.

Error Handling Test:

  • Log out of Jianshu.
  • Attempt to sync an article.
  • Verify appropriate error message is displayed: "简书创建文章失败,请确保已登录".

No Notebook Test:

  • Create a new Jianshu account without any notebooks.
  • Attempt to sync an article.
  • Verify error message: "简书未找到文集,请先创建一个文集".

@github-actions
Copy link

🚀 Surge Preview has been successfully deployed!

Preview URL: https://doocs-md-preview-pr-1219.surge.sh

Built with commit cf58b64

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant