From 518a42b20aea09d766901ec7df1548940243bb93 Mon Sep 17 00:00:00 2001 From: Gordon Pedersen Date: Mon, 10 Feb 2025 20:52:51 +1100 Subject: [PATCH] Setup imdone for task management --- .imdone/DONE/Components/update-theme.md | 11 ++ .../DONE/Components/upload-the-profile-pic.md | 11 ++ .imdone/DONE/backlog.md | 61 +++++++++ .imdone/DONE/test.md | 12 ++ .imdone/actions/board.js | 16 +++ .imdone/actions/card.js | 4 + .imdone/config.yml | 101 ++++++++++++++ .imdone/properties/card.js | 124 ++++++++++++++++++ .imdone/style.css | 0 .imdone/tags.yml | 4 + .imdoneignore | 8 ++ Components/EditProfilePicDialog.razor | 3 - Components/PasteCard.razor | 7 +- Components/PicList.razor | 5 +- Components/ThemeDialog.razor | 1 - Models/API/AccountResponseData.cs | 5 +- Platforms/Android/MainActivity.cs | 12 +- backlog.md | 63 +++++++++ 18 files changed, 437 insertions(+), 11 deletions(-) create mode 100644 .imdone/DONE/Components/update-theme.md create mode 100644 .imdone/DONE/Components/upload-the-profile-pic.md create mode 100644 .imdone/DONE/backlog.md create mode 100644 .imdone/DONE/test.md create mode 100644 .imdone/actions/board.js create mode 100644 .imdone/actions/card.js create mode 100644 .imdone/config.yml create mode 100644 .imdone/properties/card.js create mode 100644 .imdone/style.css create mode 100644 .imdone/tags.yml create mode 100644 .imdoneignore create mode 100644 backlog.md diff --git a/.imdone/DONE/Components/update-theme.md b/.imdone/DONE/Components/update-theme.md new file mode 100644 index 0000000..2efdab0 --- /dev/null +++ b/.imdone/DONE/Components/update-theme.md @@ -0,0 +1,11 @@ +#DONE update theme + + + diff --git a/.imdone/DONE/Components/upload-the-profile-pic.md b/.imdone/DONE/Components/upload-the-profile-pic.md new file mode 100644 index 0000000..b46f9ea --- /dev/null +++ b/.imdone/DONE/Components/upload-the-profile-pic.md @@ -0,0 +1,11 @@ +#DONE upload the profile pic + + + diff --git a/.imdone/DONE/backlog.md b/.imdone/DONE/backlog.md new file mode 100644 index 0000000..1e2f554 --- /dev/null +++ b/.imdone/DONE/backlog.md @@ -0,0 +1,61 @@ + +## Must Haves +- {check} View [latest statuslog entries](https://api.omg.lol/statuslog/latest) +- {check} View [all statuses of a single person](https://api.omg.lol/address/adam/statuses) (get [profile picture](https://profiles.cache.lol/adam/picture) and [statuslog bio](https://api.omg.lol/address/adam/statuses/bio)) Note: I'm calling this the profile page (even though omg.lol profile is a different thing) +- {check} [Log in](https://home.omg.lol/oauth/authorize?client_id=ea14dafd3e92cbcf93750c35cd81a031&scope=everything&redirect_uri=https://neatnik.net/adam/bucket/omgloloauth/&response_type=code) and [Authenticate](https://api.omg.lol/#token-get-oauth-exchange-an-authorization-code-for-an-access-token) (then [get all addresses](https://api.omg.lol/account/application/addresses) so we can pick one for other interactions) +- {check} Post a [new status](https://api.omg.lol/#token-post-statuslog-share-a-new-status) (checkbox for posting to mastodon) +- {check} Log out +- {check} Light/Dark themes (based on system theme) + +## Should Haves +- {check} Share statuses, etc. +- {check} Have a character counter on statuses and a warning if going over length for posting to Mastodon. +- {check} Be a share target for creating statuses +- {check} View the [address directory](https://api.omg.lol/directory) (showing profile pics and linking to profile page) + - {check} Link to it via the account menu (There's not a lot of room in the nav) +- {check} View the [now garden](https://api.omg.lol/now/garden) (also, perhaps cache the now garden and link to the now page on a person's profile) +- {check} Updated profile page. Shows: + - {check} [profile picture](https://profiles.cache.lol/adam/picture) + - {check} [statuslog bio](https://api.omg.lol/address/adam/statuses/bio) text + - {check} [all statuses](https://api.omg.lol/address/adam/statuses) + - {check} Link to now page (if present in [now garden](https://api.omg.lol/now/garden)) + - {check} Link to profile page (aka web page) + - {check} Link to person's some.pics + - {check} Link to person's pastebin + +## Want to Haves +- {check} [Some.pics feed](https://api.omg.lol/pics) (plus seeing the some.pics of individuals, link on profile) +- {check} Be a share target for pictures +- {check} [Ephemeral feed](https://eph.emer.al/) + - {check} plus posting - ~~if/when an API becomes available~~ (Thanks Adam 😁) +- {check} Upload pics +- {check} Edit some.pics +- {check} delete pics +- {check} Edit statuses +- {check} delete statuses +- {check} Update / manage [now page](https://api.omg.lol/#now-page) +- {square} pull to refresh +- {check} Follow people (i.e. locally bookmark their statuslog profile) + - {check} A combined feed of all statuses and pics of everyone you're following + +## Nice to Haves +- {check} Update profile picture +- {check} Update / manage statuslog bio +- {check} Update / manage [profile/web page](https://api.omg.lol/#web) + - {check} including [themes](https://api.omg.lol/#theme) +- {check} Update / manage [pastebin](https://api.omg.lol/#pastebin) + - {check} share and copy items + - {check} view as markup + - {check} visible in profile page + - {check} visible in feed + +## Current Bugs +- {check} ~~Sharing to app multiple times throws an exception~~ +- {check} ~~Need to update "Loading", "Logging in" and "nothing here" pages to match the splash screen (ish)~~ +- {check} ~~Empty bio on person/statuses (just remove the div if the bio is empty)~~ +- {check} ~~Need warnings on pics with no description~~ +- {check} ~~respond appears on statuses with no external link~~ +- {check} ~~statuses / pics don't refresh on update/delete~~ +- {check} ~~own now page isn't showing properly in profile~~ +- {check} ~~statuses with long words or urls won't wrap.~~ +- {check} ~~Ephemeral scraping doesn't send a user agent string, so no longer works.~~ \ No newline at end of file diff --git a/.imdone/DONE/test.md b/.imdone/DONE/test.md new file mode 100644 index 0000000..78b3f1f --- /dev/null +++ b/.imdone/DONE/test.md @@ -0,0 +1,12 @@ +#DONE test + + + diff --git a/.imdone/actions/board.js b/.imdone/actions/board.js new file mode 100644 index 0000000..77445c3 --- /dev/null +++ b/.imdone/actions/board.js @@ -0,0 +1,16 @@ +const path = require('path') + +module.exports = function () { + const project = this.project + return [ + { + title: "Open in vscode", // This is what displays in the main menu + keys: ['alt+o'], // This is the keyboard shortcut + icon: "code", // This is the font awesome icon that displays in the main menu + action (task) { + const url = `vscode://file/${path.join(project.path, task.path)}:${task.line}` + project.openUrl(url) + } + } + ] +} diff --git a/.imdone/actions/card.js b/.imdone/actions/card.js new file mode 100644 index 0000000..b30d958 --- /dev/null +++ b/.imdone/actions/card.js @@ -0,0 +1,4 @@ +module.exports = function (task) { + const project = this.project + return [] +} diff --git a/.imdone/config.yml b/.imdone/config.yml new file mode 100644 index 0000000..1105467 --- /dev/null +++ b/.imdone/config.yml @@ -0,0 +1,101 @@ +keepEmptyPriority: false +languages: + .razor: + name: razor + symbol: "//" + block: + start: "@*" + end: "*@" + ignore: "*" +code: + include_lists: + - TODO + - DOING + - DONE + - PLANNING + - FIXME + - ARCHIVE + - HACK + - CHANGED + - XXX + - IDEA + - NOTE + - REVIEW + - WAITING +lists: + - name: NOTE + hidden: false + id: 9886o1muwm6yiizyq + - name: Past Due Reminders + hidden: true + ignore: false + filter: 'remind = /./ and remind < "${now}" and list != DONE -remind' + id: 9886o1muwm6yiizyr + - name: What's Due? + hidden: true + ignore: false + filter: 'dueDate < "${in 15 days}" AND list != DONE +dueDate +order' + id: 9886o1muwm6yiizys + - name: WAITING + hidden: false + ignore: false + id: 9886o10uwm6yovnxl + - name: TODO + hidden: false + id: 9886o1muwm6yiizyt + - name: DOING + hidden: false + id: 9886o1muwm6yiizyu + - name: DONE + hidden: false + ignore: true + id: 9886o1muwm6yiizyv + - name: Recently Completed + filter: 'completedDate > "${14 days ago}" -completed' + hidden: false + id: 9886o1muwm6yiizyw +settings: + '0': object Object + openIn: default + openCodeIn: default + journalType: Single File + journalPath: null + appendNewCardsTo: backlog.md + newCardSyntax: MARKDOWN + replaceSpacesWith: '-' + plugins: {} + journalTemplate: null + markdownOnly: false + kudosProbability: 0.33 + views: [] + name: Neighbourhood.omg.lol + cards: + colors: + - color: red + filter: tags = "BUG" + - color: black + filter: tags = "Someday" + - color: green + filter: tags = "WantToHave" + template: | + + + trackChanges: false + metaNewLine: true + addCompletedMeta: true + addCheckBoxTasks: false + doneList: DONE + tokenPrefix: '#' + taskPrefix: '' + tagPrefix: '#' + metaSep: ':' + orderMeta: true + maxLines: 6 + addNewCardsToTop: true + showTagsAndMeta: false + defaultList: TODO + computed: ! '' + archiveCompleted: true + archiveFolder: .imdone/DONE diff --git a/.imdone/properties/card.js b/.imdone/properties/card.js new file mode 100644 index 0000000..d2da139 --- /dev/null +++ b/.imdone/properties/card.js @@ -0,0 +1,124 @@ +let updatedAt = new Date() + +module.exports = function ({ line, source, totals }) { + const project = this.project + + const emoji = { + due: dueEmoji(totals), + recent: recentEmoji(totals), + wip: wipEmoji(totals), + chart: EMOJI.CHART + } + + // These are the properties that are available to use in your cards + // Use ${property_name} to permanently insert the value of the property + // Use {{property_name}} to insert the value of the property at runtime + return { + date: `${new Date().toISOString().substring(0, 10)}`, + sourceLink: `[${source.path}:${line}](${source.path}:${line})`, + cardTotal: cardTotal(totals), + allTopics: project.allTopics, // This is an array of all the topics in the project + topicTable: getTopicTable(project), // This is a markdown table with the count of tasks for each topic/list intersection + emoji, + icons + } +} + +const icons = { + filter: `` + ,openFile: `` + ,kebab: `` + ,clone: `` + ,editCard: `` +} + +const EMOJI = { + BAD: ':rotating_light:', + GREAT: ':rocket:', + SLEEP: ':sleeping:', + GOOD: ':2nd_place_medal:', + CHART: ':chart:' +} + +function formatEmoji(emoji) { + return `${emoji}` +} + +function dueEmoji(totals) { + const due = totals["What's Due?"] + let emoji = EMOJI.GOOD + if (due >= 3) { + emoji = EMOJI.BAD + } else if (due === 0) { + emoji = EMOJI.GREAT + } + return formatEmoji(emoji) +} + +function recentEmoji(totals) { + const recentlyCompleted = totals['Recently Completed'] + let emoji = EMOJI.GOOD + if (recentlyCompleted >= 3) { + emoji = EMOJI.GREAT + } else if (recentlyCompleted === 0) { + emoji = EMOJI.BAD + } + return formatEmoji(emoji) +} + +function wipEmoji(totals) { + const doing = totals['DOING'] + let emoji = EMOJI.GOOD + if (doing >= 3) { + emoji = EMOJI.BAD + } else if (doing === 0) { + emoji = EMOJI.SLEEP + } else if (doing === 1) { + emoji = EMOJI.GREAT + } + return formatEmoji(emoji) +} + +function cardTotal(totals) { + let count = 0 + Object.keys(totals).forEach((list) => { + count += totals[list] + }) + return count +} + +function getTopicTable(project) { + console.log('project.updatedAt', project.updatedAt) + console.log('updatedAt', updatedAt) + if (project.updatedAt < updatedAt) return '' + + updatedAt = project.updatedAt + const lists = project.allLists.filter(list => !list.filter) + const topicTable = project.allTopics.map((topic) => { + return { + name: topic, + lists: [ + ...lists.map((list) => { + return { + name: list.name, + count: list.tasks.filter((task) => task.topics.includes(topic)).length + } + }) + ] + } + }); + + //convert topic table into a markdown table with topic name on the left and list names on the top and the count for each topic/list intersection + const table = ` +| Topic | ${lists.map((list) => list.name).join(' | ')} | +| --- | ${lists.map(() => ' --- ').join(' | ')} | +${topicTable.map((topic) => { + const topicLink = `imdone://${project.path}?filter=topics="${encodeURIComponent(topic.name)}"`; + return `| [[${topic.name}]] | ${topic.lists.map((list) => `[${list.count}](${topicLink})`).join(' | ')} |`; +}).join('\n')} +`; + + console.log(table); + return table +} + diff --git a/.imdone/style.css b/.imdone/style.css new file mode 100644 index 0000000..e69de29 diff --git a/.imdone/tags.yml b/.imdone/tags.yml new file mode 100644 index 0000000..af64e7a --- /dev/null +++ b/.imdone/tags.yml @@ -0,0 +1,4 @@ +tags: + - BUG + - Someday + - WantToHave diff --git a/.imdoneignore b/.imdoneignore new file mode 100644 index 0000000..2aa81cf --- /dev/null +++ b/.imdoneignore @@ -0,0 +1,8 @@ +.vs +bin +obj +*.user +.imdone +Resources +.git +.vscode \ No newline at end of file diff --git a/Components/EditProfilePicDialog.razor b/Components/EditProfilePicDialog.razor index b45e0a2..14cb900 100644 --- a/Components/EditProfilePicDialog.razor +++ b/Components/EditProfilePicDialog.razor @@ -57,11 +57,8 @@ loading = true; await InvokeAsync(StateHasChanged); - //TODO: upload the profile pic - //PutPicResponseData? response = await api.PutPic(State.SelectedAddressName!, Base64File!); if (Base64File != null && File != null) { - // using var fileStream = await File.OpenReadAsync(); BasicResponseData? response = await api.PostProfilePic(Address!, File); if (response != null) { diff --git a/Components/PasteCard.razor b/Components/PasteCard.razor index 666f7fd..53633b8 100644 --- a/Components/PasteCard.razor +++ b/Components/PasteCard.razor @@ -2,7 +2,12 @@ @inject IJSRuntime JS
- @* TODO: link to paste view *@ + @* TODO link to paste view + * + *@ +