Skip to content

Commit

Permalink
Improvements to Post Tweet Mode (#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
chhoumann authored Apr 3, 2021
1 parent 02794f3 commit 4ea10a2
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 47 deletions.
18 changes: 10 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,18 @@ You'll see an indicator which tells you if you're connected or not.
## Post Tweet Mode
Using the `Post Tweet` command, a new modal will open. There, you can craft threads - or single tweets.
You can select both text or threads before using the command and it'll automatically port it into the modal. If the selected text is longer than 280 characters, it'll break it into a thread for you.
You can paste text into the modal. If that text is longer than 280 characters, it'll also break it into multiple tweets. The tweets are added below the one you're pasting to.
You can paste text into the modal. If that text is longer than 280 characters, it'll also break it into multiple tweets.

### Post Tweet Mode Shortcuts
- Backspace to delete empty tweet
- Enter to make new tweet if max length
- Alt + Enter to make new tweet
- Ctrl + Enter to insert a tweet below
- Shift + Enter to insert a new tweet above
- Ctrl + ArrowUp to focus tweet above
- Ctrl + ArrowDown to focus tweet below
- `Backspace` to delete empty tweet
- `Enter` to make new tweet if max length
- `Alt + Enter` to make new tweet
- `Ctrl + Enter` to insert a tweet below
- `Shift + Enter` to insert a new tweet above
- `Ctrl + ArrowUp` to focus tweet above
- `Ctrl + ArrowDown` to focus tweet below
- `Ctrl + Shift + ArrowUp` to move tweet up
- `Ctrl + Shift + ArrowDown` to move tweet down

## Quick-posts
Single tweets are simple. Just select some text and use the `Post Selected as Tweet` command.
Expand Down
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "notetweet",
"name": "NoteTweet🐦",
"version": "0.3.0",
"version": "0.3.1",
"minAppVersion": "0.9.12",
"description": "This plugin allows you to post tweets directly from Obsidian.",
"author": "Christian B. B. Houmann",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "notetweet",
"version": "0.3.0",
"version": "0.3.1",
"description": "Post tweets from Obsidian",
"main": "src/main.js",
"scripts": {
Expand Down
115 changes: 78 additions & 37 deletions src/Modals/PostTweetModal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,20 @@ export class PostTweetModal extends Modal {
// Separate lines by linebreaks. Add lines together, separated by linebreak, if they can fit within a tweet.
// Repeat this until all separated lines are joined into tweets with proper sizes.
private textInputHandler(str: string) {
let chunks: string[] = str.split("\n").map(txt => txt.trim());
let chunks: string[] = str.split("\n");
let i = 0, joinedTextChunks: string[] = [];
chunks.forEach((chunk, j) => {
if (joinedTextChunks[i] == null) joinedTextChunks[i] = "";
if (joinedTextChunks[i].length + chunk.length <= this.MAX_TWEET_LENGTH - 1) {
joinedTextChunks[i] = joinedTextChunks[i] + chunk.trim();
joinedTextChunks[i] = joinedTextChunks[i] + chunk;
joinedTextChunks[i] += (j == chunks.length - 1) ? "" : "\n";
} else {
joinedTextChunks[++i] = chunk;
if (chunk.length > this.MAX_TWEET_LENGTH) {
let x = chunk.split(/[.?!]\s/).join("\n");
this.textInputHandler(x).forEach(split => joinedTextChunks[++i] = split);
} else {
joinedTextChunks[++i] = chunk;
}
}
})
return joinedTextChunks;
Expand Down Expand Up @@ -131,7 +136,8 @@ export class PostTweetModal extends Modal {
let pasted: string = event.clipboardData.getData("text");
if (pasted.length + textarea.textLength > this.MAX_TWEET_LENGTH) {
event.preventDefault();
this.insertTweetBelow(textarea, textZone, pasted);
let splicedPaste = this.textInputHandler(pasted);
this.createTweetsWithInput(splicedPaste, textarea, textZone);
}
};
}
Expand Down Expand Up @@ -173,23 +179,49 @@ export class PostTweetModal extends Modal {
this.insertTweetBelow(textarea, textZone);
}

if (key.code == "ArrowUp" && key.ctrlKey) {
if (key.code == "ArrowUp" && key.ctrlKey && !key.shiftKey) {
let currentTweetIndex = this.textAreas.findIndex(tweet => tweet.value == textarea.value);
if (currentTweetIndex > 0)
this.textAreas[currentTweetIndex - 1].focus()
}

if (key.code == "ArrowDown" && key.ctrlKey) {
if (key.code == "ArrowDown" && key.ctrlKey && !key.shiftKey) {
let currentTweetIndex = this.textAreas.findIndex(tweet => tweet.value == textarea.value);
if (currentTweetIndex < this.textAreas.length - 1)
this.textAreas[currentTweetIndex + 1].focus()
this.textAreas[currentTweetIndex + 1].focus();
}

if (key.code == "ArrowDown" && key.ctrlKey && key.shiftKey) {
let tweetIndex = this.textAreas.findIndex(ta => ta.value == textarea.value);
if (tweetIndex != this.textAreas.length - 1) {
key.preventDefault();
this.switchTweets(textarea, this.textAreas[tweetIndex + 1]);
this.textAreas[tweetIndex + 1].focus();
}
}

if (key.code == "ArrowUp" && key.ctrlKey && key.shiftKey) {
let tweetIndex = this.textAreas.findIndex(ta => ta.value == textarea.value);
if (tweetIndex != 0) {
key.preventDefault();
this.switchTweets(textarea, this.textAreas[tweetIndex - 1]);
this.textAreas[tweetIndex - 1].focus();
}
}

textarea.style.height = "auto";
textarea.style.height = (textarea.scrollHeight) + "px";
};
}

private switchTweets(textarea1: HTMLTextAreaElement, textarea2: HTMLTextAreaElement) {
let temp: string = textarea1.value;
textarea1.value = textarea2.value;
textarea2.value = temp;
textarea1.dispatchEvent(new InputEvent('input'));
textarea2.dispatchEvent(new InputEvent('input'));
}

private deleteTweet(textarea: HTMLTextAreaElement, textZone: HTMLDivElement, lengthCheckerEl: HTMLElement) {
let i = this.textAreas.findIndex(ele => ele === textarea);
this.textAreas.remove(textarea);
Expand Down Expand Up @@ -227,8 +259,8 @@ export class PostTweetModal extends Modal {
return async () => {
let threadContent = this.textAreas.map(textarea => textarea.value);

if (threadContent.find(txt => txt.length > this.MAX_TWEET_LENGTH)) {
new Notice("At least one of your tweets is too long.");
if (threadContent.find(txt => txt.length > this.MAX_TWEET_LENGTH || txt == "") != null) {
new Notice("At least one of your tweets is too long or empty.");
return;
}

Expand All @@ -248,54 +280,63 @@ export class PostTweetModal extends Modal {
let insertAboveIndex = this.textAreas.findIndex(area => area.value == textarea.value);

try {
this.createTextarea(textZone);
let insertedTweet = this.createTextarea(textZone);
this.shiftTweetsDownFromIndex(insertAboveIndex);

return {tweet: insertedTweet, index: insertAboveIndex}
}
catch (e) {
new Notice(e);
return;
}

// Shift all elements below down
for (let i = this.textAreas.length - 1; i > insertAboveIndex; i--){
this.textAreas[i].value = this.textAreas[i - 1].value;
this.textAreas[i].dispatchEvent(new InputEvent('input'));
}

this.textAreas[insertAboveIndex].value = "";
this.textAreas[insertAboveIndex].focus();
}

private insertTweetBelow(textarea: HTMLTextAreaElement, textZone: HTMLDivElement, insertText?: string) {
private insertTweetBelow(textarea: HTMLTextAreaElement, textZone: HTMLDivElement) {
let insertBelowIndex = this.textAreas.findIndex(area => area.value == textarea.value);
let insertedIndex = insertBelowIndex + 1;
let fromIndex = insertBelowIndex + 1;

try {
this.createTextarea(textZone);
let insertedTextarea = this.createTextarea(textZone);
this.shiftTweetsDownFromIndex(fromIndex);

return insertedTextarea;
}
catch (e) {
new Notice(e);
return;
}
}

// Shift all elements below down
for (let i = this.textAreas.length - 1; i > insertedIndex; i--){
private shiftTweetsDownFromIndex(insertedIndex: number) {
for (let i = this.textAreas.length - 1; i > insertedIndex; i--) {
this.textAreas[i].value = this.textAreas[i - 1].value;
this.textAreas[i].dispatchEvent(new InputEvent('input'));
}

if (insertText != null) {
if (insertText.length > this.MAX_TWEET_LENGTH) {
let sliced = this.textInputHandler(insertText);
this.textAreas[insertedIndex].value = sliced[0];
this.insertTweetBelow(this.textAreas[insertedIndex - 1], textZone, sliced.slice(1).join());
}
if (insertText.length <= this.MAX_TWEET_LENGTH)
this.textAreas[insertedIndex].value = insertText;
this.textAreas[insertedIndex].value = "";
this.textAreas[insertedIndex].focus();
}

/* private insertTweetBelowWithText(textarea: HTMLTextAreaElement, textZone: HTMLDivElement, insertText: string){
// Insert tweet, assign to var. Pass that var in again.
// It'll be reverse order if I don't insert below each one. For inserting above, you can just insert as you normally would.
if (insertText.length > this.MAX_TWEET_LENGTH) {
let sliced = this.textInputHandler(insertText); // First, make sure the text is sized correctly.
let tweet: HTMLTextAreaElement = textarea;
let tweetIndex = this.insertTweetBelow(tweet, textZone);
tweet = this.textAreas[tweetIndex];
this.insertTweetBelowWithText(tweet, textZone, sliced.slice(1).join());
// sliced.forEach(chunk => {
// console.log("!!!!")
// let x = this.insertTweetBelow(tweet, textZone);
// tweet = x.insertedTweet;
// tweet.value = chunk;
// });
}
else {
this.textAreas[insertedIndex].value = "";
let {insertedTweet, insertedIndex} = this.insertTweetBelow(textarea, textZone);
this.textAreas[insertedIndex].value = insertText;
}

this.textAreas[insertedIndex].focus();
}
}*/
}

0 comments on commit 4ea10a2

Please sign in to comment.