-
Notifications
You must be signed in to change notification settings - Fork 44
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
New script: Quick Queue #4
Closed
Closed
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
0e756aa
Start to attempt to make quick actions
invalidCards fd586a6
make it gooder
invalidCards 3e673d6
Add user blog utility
invalidCards 1a858c8
Apply new ESLint rules
invalidCards cea7bd2
Use proper object structure for default blog
invalidCards bd2cd45
Rebranding and something called "UX"
invalidCards 83ab15d
Merge branch 'master' into quickactions
invalidCards 81d87d8
Apply suggestions from code review
invalidCards cf98cae
Implement feedback
invalidCards 6b87d0c
Apply suggestions from code review
invalidCards 7487e8a
Trim down post parameters to the bare necessities
invalidCards File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ | |
"cleanfeed", | ||
"disable_gifs", | ||
"painter", | ||
"quick_queue", | ||
"timestamps", | ||
"tweaks" | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
.xkit_quick_queue_container { | ||
font-family: var(--font-family); | ||
font-size: 1rem; | ||
font-weight: 700; | ||
margin-left: 20px; | ||
position: relative; | ||
line-height: 1; | ||
} | ||
|
||
.xkit_quick_queue_container_span { | ||
vertical-align: top; | ||
display: inline-block; | ||
width: inherit; | ||
} | ||
|
||
.xkit_quick_queue_button { | ||
color: inherit; | ||
font: inherit; | ||
} | ||
|
||
.xkit_quick_queue_button_inner { | ||
display: block; | ||
color: inherit; | ||
font: inherit; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
(function() { | ||
let controlsSelector; | ||
const queuePath = '<path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16zm1-8h4v2h-6V7h2v5z"/>'; | ||
const errorCrossPath = '<path d="M12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z"/>'; | ||
const loadPath = '<path d="M5.463 4.433A9.961 9.961 0 0 1 12 2c5.523 0 10 4.477 10 10 0 2.136-.67 4.116-1.81 5.74L17 12h3A8 8 0 0 0 6.46 6.228l-.997-1.795zm13.074 15.134A9.961 9.961 0 0 1 12 22C6.477 22 2 17.523 2 12c0-2.136.67-4.116 1.81-5.74L7 12H4a8 8 0 0 0 13.54 5.772l.997 1.795z"/>'; | ||
const draftPath = '<path d="M21 8v12.993A1 1 0 0 1 20.007 22H3.993A.993.993 0 0 1 3 21.008V2.992C3 2.455 3.449 2 4.002 2h10.995L21 8zm-2 1h-5V4H5v16h14V9z"/>'; | ||
|
||
const quickQueue = async function(event) { | ||
const postElement = event.target.closest('div[data-id]'); | ||
if (!postElement) { | ||
event.target.innerHTML = errorCrossPath; | ||
event.target.setAttribute('fill', 'var(--red)'); | ||
return; | ||
} | ||
event.target.innerHTML = loadPath; | ||
const post_id = postElement.dataset.id; | ||
|
||
const { apiFetch } = await fakeImport('/src/util/tumblr-helpers.js'); | ||
const { timelineObject } = await fakeImport('/src/util/react-props.js'); | ||
const { fetchDefaultBlog } = await fakeImport('/src/util/user-blogs.js'); | ||
|
||
const {uuid: defaultBlogUuid = ''} = await fetchDefaultBlog(); | ||
|
||
const {blog, reblogKey} = await timelineObject(post_id); | ||
try { | ||
const response = await apiFetch(`/v2/blog/${defaultBlogUuid}/posts`, {method: 'POST', | ||
body: { | ||
state: 'queue', | ||
parent_tumblelog_uuid: blog.uuid, | ||
parent_post_id: post_id, | ||
reblog_key: reblogKey, | ||
}}); | ||
if ([200, 201].includes(response.meta.status)) { | ||
event.target.innerHTML = queuePath; | ||
event.target.setAttribute('fill', 'var(--green)'); | ||
} else { | ||
event.target.innerHTML = errorCrossPath; | ||
event.target.setAttribute('fill', 'var(--red)'); | ||
} | ||
} catch (e) { | ||
if (e.status === 400) { | ||
try { | ||
const draftResponse = await apiFetch(`/v2/blog/${defaultBlogUuid}/posts`, {method: 'POST', | ||
body: { | ||
state: 'draft', | ||
parent_tumblelog_uuid: blog.uuid, | ||
parent_post_id: post_id, | ||
reblog_key: reblogKey, | ||
}}); | ||
if ([200, 201].includes(draftResponse.meta.status)) { | ||
event.target.innerHTML = draftPath; | ||
event.target.setAttribute('fill', 'var(--green)'); | ||
} else { | ||
event.target.innerHTML = errorCrossPath; | ||
event.target.setAttribute('fill', 'var(--red)'); | ||
} | ||
} catch (err) { | ||
event.target.innerHTML = errorCrossPath; | ||
event.target.setAttribute('fill', 'var(--red)'); | ||
console.error(err.body); | ||
} | ||
} else { | ||
event.target.innerHTML = errorCrossPath; | ||
event.target.setAttribute('fill', 'var(--red)'); | ||
console.error(e.body); | ||
} | ||
} | ||
}; | ||
|
||
const addButtons = async function() { | ||
const { timelineObject } = await fakeImport('/src/util/react-props.js'); | ||
const { translate } = await fakeImport('/src/util/language-data.js'); | ||
|
||
const reblogButtonAriaLabel = await translate('Reblog'); | ||
|
||
[...document.querySelectorAll('[data-id]:not(.xkit_quick_queue_done)')] | ||
.forEach(async postElement => { | ||
postElement.classList.add('xkit_quick_queue_done'); | ||
|
||
const post_id = postElement.dataset.id; | ||
const {canReblog} = await timelineObject(post_id); | ||
|
||
if (canReblog) { | ||
const controls = postElement.querySelector(controlsSelector); | ||
|
||
const queueButtonContainer = document.createElement('div'); | ||
queueButtonContainer.classList.add('xkit_quick_queue_container'); | ||
|
||
const queueButtonContainerSpan = document.createElement('span'); | ||
queueButtonContainerSpan.classList.add('xkit_quick_queue_container_span'); | ||
|
||
const queueButton = document.createElement('button'); | ||
queueButton.classList.add('xkit_quick_queue_button'); | ||
queueButton.addEventListener('click', quickQueue); | ||
queueButton.tabIndex = 0; | ||
|
||
const queueButtonInner = document.createElement('span'); | ||
queueButtonInner.classList.add('xkit_quick_queue_button_inner'); | ||
queueButtonInner.tabIndex = -1; | ||
queueButtonInner.innerHTML = `<svg viewBox="2 2 20 20" width="21" height="21" fill="var(--gray-65)">${queuePath}</svg>`; | ||
|
||
queueButton.appendChild(queueButtonInner); | ||
queueButtonContainerSpan.appendChild(queueButton); | ||
queueButtonContainer.appendChild(queueButtonContainerSpan); | ||
|
||
const reblogButton = postElement.querySelector(`[aria-label="${reblogButtonAriaLabel}"]`).parentElement; | ||
controls.insertBefore(queueButtonContainer, reblogButton); | ||
} | ||
}); | ||
}; | ||
|
||
const main = async function() { | ||
const { postListener } = await fakeImport('/src/util/mutations.js'); | ||
const { keyToCss } = await fakeImport('/src/util/css-map.js'); | ||
controlsSelector = await keyToCss('controls'); | ||
|
||
postListener.addListener(addButtons); | ||
addButtons(); | ||
}; | ||
|
||
const clean = async function() { | ||
const { postListener } = await fakeImport('/src/util/mutations.js'); | ||
postListener.removeListener(addButtons); | ||
$('.xkit_quick_queue_container').remove(); | ||
}; | ||
|
||
const stylesheet = 'src/scripts/quick_queue.css'; | ||
|
||
return { main, clean, stylesheet }; | ||
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"title": "Quick Queue", | ||
"description": "Add a button to quickly queue posts, or draft them if your queue is full", | ||
"icon": { | ||
"class_name": "ri-flashlight-line", | ||
"color": "white", | ||
"background_color": "#b820f9" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
(function() { | ||
let userBlogs; | ||
|
||
/** | ||
* @return {Object[]} - An array of blog objects the current user has post access to | ||
*/ | ||
const fetchUserBlogs = async function() { | ||
if (!userBlogs) { | ||
const { apiFetch } = await fakeImport('/src/util/tumblr-helpers.js'); | ||
const response = await apiFetch('/v2/user/info'); | ||
if (response.meta.status === 200) { | ||
userBlogs = response.response.user.blogs; | ||
} | ||
} | ||
|
||
return userBlogs; | ||
}; | ||
|
||
/** | ||
* @return {String[]} - An array of blog names the current user has post access to | ||
*/ | ||
const fetchUserBlogNames = async function() { | ||
const blogs = await fetchUserBlogs(); | ||
return blogs.map(blog => blog.name); | ||
}; | ||
|
||
/** | ||
* @return {String} - The default ("main") blog for the user | ||
*/ | ||
const fetchDefaultBlog = async function() { | ||
const blogs = await fetchUserBlogs(); | ||
return blogs.find(blog => blog.primary === true); | ||
}; | ||
|
||
return { fetchUserBlogs, fetchUserBlogNames, fetchDefaultBlog }; | ||
})(); |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'm fairly sure that OK-checking here is unnecessary, given that at least 4xx errors result in
apiFetch
rejecting, but we may want to wait on official documentation (tumblr/docs#25)