Initial commit: uuu.gl Markdown Uploader v1.3.4

This commit is contained in:
john 2025-11-05 12:18:41 +09:00
commit 3245184d83
5 changed files with 23198 additions and 0 deletions

29
.gitignore vendored Normal file
View file

@ -0,0 +1,29 @@
# Node
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Build
lib/
dist/
*.js.map
# IDE
.idea/
.vscode/
*.swp
*.swo
*~
# OS
.DS_Store
Thumbs.db
# Obsidian
data.json
# Misc
*.log
.env
.env.local

95
README.md Normal file
View file

@ -0,0 +1,95 @@
# uuu.gl Markdown Uploader for Obsidian
Upload your Obsidian notes to [uuu.gl](https://uuu.gl) as beautifully rendered Markdown documents with all images and internal links preserved.
## Features
**One-Click Upload** - Upload your notes directly from Obsidian
📸 **Image Preservation** - Automatically uploads and embeds all images
🔗 **Custom Short URLs** - Create memorable URLs like `uuu.gl/my-note`
🔒 **Password Protection** - Optionally protect your notes with a password
💾 **Auto-Save** - Real-time auto-save with version control
🎨 **Beautiful Rendering** - GitHub Flavored Markdown with syntax highlighting
## How It Works
1. Write your note in Obsidian
2. Click the upload icon or use the command palette
3. Choose a custom shortcode (e.g., `my-note`)
4. Your note is instantly available at `https://uuu.gl/my-note`
## Installation
### From Obsidian Community Plugins
1. Open Settings → Community Plugins
2. Search for "uuu.gl"
3. Click Install
4. Enable the plugin
### Manual Installation
1. Download `main.js`, `manifest.json`, and `styles.css` from the [latest release](https://github.com/johnkim05/obsidian-uuugl-plugin/releases)
2. Create a folder named `uuugl-uploader` in your vault's `.obsidian/plugins/` directory
3. Move the downloaded files into the folder
4. Reload Obsidian and enable the plugin in Settings → Community Plugins
## Usage
### Upload a Note
**Method 1: Ribbon Icon**
- Click the cloud upload icon in the left sidebar
**Method 2: Command Palette**
- Press `Cmd/Ctrl + P`
- Type "Upload current note to uuu.gl"
- Press Enter
**Method 3: Custom Hotkey**
- Set a custom hotkey in Settings → Hotkeys
- Search for "uuu.gl: Upload current note"
### Options
- **Custom Shortcode**: Create memorable URLs (e.g., `meeting-notes`)
- **Random Shortcode**: Generate a random 8-character code
- **Password Protection**: Add a password to protect your note
### Status Bar
After uploading, the status bar shows your note's URL. Click to copy!
```
🔗 my-note ← Click to copy full URL
```
## Settings
- **Default Shortcode Prefix**: Customize the prefix for auto-generated shortcodes (default: `obsidian`)
- **Google Sign In**: Sign in to track your uploads and manage them at [uuu.gl/my-memos](https://uuu.gl/my-memos)
## Privacy
- **Anonymous Uploads**: You can upload without signing in
- **User Data**: We only store your email if you choose to sign in with Google
- **Content**: Your notes are stored securely on Firebase
- **Deletion**: You can delete your uploads anytime from the uuu.gl website
## Support
- **Website**: [uuu.gl](https://uuu.gl)
- **Issues**: [GitHub Issues](https://github.com/johnkim05/obsidian-uuugl-plugin/issues)
- **Email**: john050151@gmail.com
## License
MIT License - feel free to use and modify!
## Credits
Developed by [uuu.gl](https://uuu.gl)
---
**Note**: This plugin requires an internet connection to upload notes to uuu.gl servers.

22568
main.js Normal file

File diff suppressed because one or more lines are too long

10
manifest.json Normal file
View file

@ -0,0 +1,10 @@
{
"id": "uuugl-uploader",
"name": "uuu.gl Markdown Uploader",
"version": "1.3.4",
"minAppVersion": "0.15.0",
"description": "Upload Obsidian notes to uuu.gl as rendered Markdown documents with internal links preserved",
"author": "uuu.gl",
"authorUrl": "https://uuu.gl",
"isDesktopOnly": true
}

496
styles.css Normal file
View file

@ -0,0 +1,496 @@
/* uuu.gl Markdown Uploader Plugin Styles */
/* Minimalist design following Obsidian's default aesthetic */
/* ===== Modal Container ===== */
.uuugl-upload-modal {
padding: 0 !important;
}
.uuugl-upload-modal .modal-content {
padding: 0 !important;
}
/* ===== Header ===== */
.uuugl-modal-header {
padding: 20px 24px;
border-bottom: 1px solid var(--background-modifier-border);
}
.uuugl-modal-header h2 {
margin: 0 0 8px 0;
font-size: 18px;
font-weight: 600;
color: var(--text-normal);
}
.uuugl-file-name {
margin: 0;
font-size: 13px;
color: var(--text-muted);
font-family: var(--font-monospace);
}
/* ===== Main Content ===== */
.uuugl-modal-content {
padding: 20px 24px 24px 24px;
}
/* ===== Section ===== */
.uuugl-section {
margin-bottom: 20px;
}
.uuugl-section-title {
margin: 0 0 12px 0;
font-size: 14px;
font-weight: 600;
color: var(--text-normal);
}
/* ===== URL Input Container ===== */
.uuugl-url-input-container {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 12px;
padding: 10px 12px;
background-color: var(--background-secondary);
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
}
.uuugl-url-prefix,
.uuugl-url-separator {
font-size: 14px;
color: var(--text-muted);
font-family: var(--font-monospace);
white-space: nowrap;
}
.uuugl-keyword-input {
flex: 1;
min-width: 80px;
padding: 4px 8px;
border: 1px solid var(--background-modifier-border);
border-radius: 3px;
background-color: var(--background-primary);
color: var(--text-normal);
font-family: var(--font-monospace);
font-size: 13px;
}
.uuugl-keyword-input:focus {
outline: none;
border-color: var(--interactive-accent);
}
.uuugl-keyword-input::placeholder {
color: var(--text-faint);
}
/* ===== Buttons ===== */
.uuugl-btn {
padding: 8px 16px;
border-radius: 4px;
font-size: 13px;
font-weight: 500;
cursor: pointer;
transition: background-color 0.15s ease;
border: none;
width: 100%;
text-align: center;
}
.uuugl-btn-primary {
background-color: var(--interactive-accent);
color: var(--text-on-accent);
}
.uuugl-btn-primary:hover {
background-color: var(--interactive-accent-hover);
}
.uuugl-btn-secondary {
background-color: var(--background-secondary);
color: var(--text-normal);
border: 1px solid var(--background-modifier-border);
}
.uuugl-btn-secondary:hover {
background-color: var(--background-modifier-hover);
}
/* ===== Divider ===== */
.uuugl-divider {
display: flex;
align-items: center;
text-align: center;
margin: 16px 0;
}
.uuugl-divider::before,
.uuugl-divider::after {
content: '';
flex: 1;
border-bottom: 1px solid var(--background-modifier-border);
}
.uuugl-divider span {
padding: 0 12px;
font-size: 12px;
color: var(--text-muted);
}
/* ===== Password Section ===== */
.uuugl-password-section {
margin-top: 16px;
}
.uuugl-password-input {
width: 100%;
padding: 8px 12px;
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
background-color: var(--background-primary);
color: var(--text-normal);
font-size: 13px;
}
.uuugl-password-input:focus {
outline: none;
border-color: var(--interactive-accent);
}
/* ===== Progress ===== */
.uuugl-progress {
margin: 20px 0;
padding: 16px;
background-color: var(--background-secondary);
border-radius: 4px;
border: 1px solid var(--background-modifier-border);
}
.uuugl-progress-text {
text-align: center;
font-weight: 500;
color: var(--text-normal);
margin-bottom: 12px;
font-size: 13px;
}
.uuugl-progress-bar-container {
width: 100%;
height: 6px;
background-color: var(--background-primary);
border-radius: 3px;
overflow: hidden;
border: 1px solid var(--background-modifier-border);
}
.uuugl-progress-bar-fill {
height: 100%;
background-color: var(--interactive-accent);
border-radius: 3px;
transition: width 0.3s ease;
width: 0%;
}
/* ===== Success Container ===== */
.uuugl-success-container {
margin: 20px 0;
padding: 20px;
background-color: var(--background-secondary);
border-radius: 4px;
border: 1px solid var(--background-modifier-border);
text-align: center;
}
.uuugl-success-header {
margin-bottom: 16px;
}
.uuugl-success-title {
font-size: 15px;
font-weight: 600;
color: var(--text-normal);
margin-bottom: 12px;
}
.uuugl-success-url-section {
margin-bottom: 16px;
padding: 16px;
background-color: var(--background-primary);
border-radius: 4px;
border: 1px solid var(--background-modifier-border);
}
.uuugl-success-label {
margin: 0 0 8px 0;
font-size: 12px;
font-weight: 500;
color: var(--text-muted);
text-transform: uppercase;
}
.uuugl-success-url {
display: block;
font-size: 14px;
font-weight: 500;
color: var(--interactive-accent);
text-decoration: none;
font-family: var(--font-monospace);
word-break: break-all;
padding: 10px 12px;
background-color: var(--background-secondary);
border-radius: 3px;
transition: background-color 0.15s ease;
border: 1px solid var(--background-modifier-border);
}
.uuugl-success-url:hover {
background-color: var(--background-modifier-hover);
text-decoration: underline;
}
.uuugl-success-buttons {
display: flex;
gap: 8px;
margin-top: 16px;
}
.uuugl-success-buttons .uuugl-btn {
flex: 1;
}
/* ===== Error Container ===== */
.uuugl-result {
margin: 20px 0;
}
.upload-modal-error {
color: var(--text-error);
font-size: 13px;
font-weight: 500;
margin-bottom: 12px;
padding: 12px 16px;
background-color: var(--background-secondary);
border-radius: 4px;
border: 1px solid var(--background-modifier-border-hover);
}
/* ===== Old styles (backward compatibility) ===== */
.upload-modal-filename {
color: var(--text-muted);
font-size: 0.9em;
margin-bottom: 1em;
}
.upload-modal-shortcode {
margin: 1.5em 0;
}
.upload-modal-shortcode label {
display: block;
margin-bottom: 0.5em;
font-weight: 600;
}
.upload-modal-keyword-row {
display: flex;
align-items: center;
gap: 0.5em;
margin-bottom: 0.75em;
}
.upload-modal-input-container {
display: flex;
align-items: center;
gap: 0.5em;
}
.upload-modal-prefix {
color: var(--text-muted);
font-size: 0.9em;
white-space: nowrap;
}
.upload-modal-input {
flex: 1;
padding: 0.5em;
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
font-family: var(--font-monospace);
min-width: 0;
}
.upload-modal-random-btn {
padding: 0.5em 1em;
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
background-color: var(--background-secondary);
cursor: pointer;
font-size: 0.9em;
transition: background-color 0.2s;
margin-top: 0.5em;
}
.upload-modal-random-btn:hover {
background-color: var(--background-modifier-hover);
}
.upload-modal-url-preview {
margin: 1em 0;
padding: 0.75em 1em;
background-color: var(--background-secondary);
border-radius: 4px;
font-size: 0.9em;
border-left: 3px solid var(--text-accent);
}
.upload-modal-url-label {
color: var(--text-muted);
}
.upload-modal-url-text {
font-family: var(--font-monospace);
word-break: break-all;
}
.upload-modal-password {
margin: 1.5em 0;
}
.upload-modal-password label {
display: block;
margin-bottom: 0.5em;
font-weight: 600;
}
.upload-modal-description {
color: var(--text-muted);
font-size: 0.85em;
margin-top: 0.5em;
}
.upload-modal-progress {
margin: 1.5em 0;
padding: 1em;
background-color: var(--background-secondary);
border-radius: 8px;
text-align: center;
font-weight: 500;
}
.upload-modal-result {
margin: 1.5em 0;
padding: 1.5em;
border-radius: 8px;
text-align: center;
}
.upload-modal-success {
color: var(--text-success);
font-size: 1.2em;
font-weight: 600;
margin-bottom: 1em;
}
.upload-modal-link {
margin: 1em 0;
padding: 1em;
background-color: var(--background-secondary);
border-radius: 4px;
word-break: break-all;
}
.upload-modal-link a {
color: var(--text-accent);
text-decoration: none;
font-family: var(--font-monospace);
}
.upload-modal-link a:hover {
text-decoration: underline;
}
.upload-modal-buttons {
display: flex;
gap: 0.5em;
justify-content: flex-end;
margin-top: 1.5em;
}
.upload-modal-buttons button {
padding: 0.5em 1.5em;
border-radius: 4px;
cursor: pointer;
}
/* ===== Existing Memo UI ===== */
.uuugl-existing-memo-section {
padding: 16px;
background-color: var(--background-secondary);
border-radius: 4px;
border: 1px solid var(--background-modifier-border);
margin-bottom: 16px;
}
.uuugl-existing-memo-title {
font-size: 14px;
font-weight: 600;
color: var(--text-normal);
margin-bottom: 12px;
}
.uuugl-existing-memo-url {
display: block;
font-size: 13px;
color: var(--interactive-accent);
font-family: var(--font-monospace);
word-break: break-all;
text-decoration: none;
padding: 8px 12px;
background-color: var(--background-primary);
border-radius: 3px;
border: 1px solid var(--background-modifier-border);
margin-bottom: 8px;
}
.uuugl-existing-memo-url:hover {
background-color: var(--background-modifier-hover);
text-decoration: underline;
}
.uuugl-existing-memo-date {
font-size: 12px;
color: var(--text-muted);
margin-top: 8px;
}
.uuugl-section-divider {
height: 1px;
background-color: var(--background-modifier-border);
margin: 20px 0;
}
.uuugl-existing-memo-buttons {
display: flex;
flex-direction: column;
gap: 8px;
}
.uuugl-btn-danger {
background-color: var(--background-secondary);
color: var(--text-error);
border: 1px solid var(--background-modifier-border);
}
.uuugl-btn-danger:hover {
background-color: var(--background-modifier-error);
border-color: var(--text-error);
}
/* ===== Settings ===== */
.setting-item-description {
margin-bottom: 1em;
}