feat: recognize hashtags in task name

This commit is contained in:
xeruf 2024-09-14 15:53:27 +03:00
parent 4b59b273f5
commit ddb68f7107
2 changed files with 29 additions and 13 deletions

View File

@ -166,9 +166,6 @@ Considering to use Calendar: https://github.com/nostr-protocol/nips/blob/master/
- Remove status filter when moving up? - Remove status filter when moving up?
- Task markdown support? - colored - Task markdown support? - colored
- Time tracking: Ability to postpone task and add planned timestamps (calendar entry) - Time tracking: Ability to postpone task and add planned timestamps (calendar entry)
- Parse Hashtag tags from task name
- Unified Filter object
-> include subtasks of matched tasks
- Speedup: Offline caching & Expiry (no need to fetch potential years of history) - Speedup: Offline caching & Expiry (no need to fetch potential years of history)
+ Fetch most recent tasks first + Fetch most recent tasks first
+ Relay: compress tracked time for old tasks, filter closed tasks + Relay: compress tracked time for old tasks, filter closed tasks

View File

@ -1,9 +1,10 @@
use itertools::Itertools; use itertools::Itertools;
use log::info; use log::info;
use nostr_sdk::{Alphabet, EventBuilder, EventId, Kind, Tag, TagStandard};
use nostr_sdk::TagStandard::Hashtag; use nostr_sdk::TagStandard::Hashtag;
use nostr_sdk::{Alphabet, EventBuilder, EventId, Kind, Tag, TagStandard};
use std::collections::HashSet;
use crate::task::{MARKER_PARENT, State}; use crate::task::{State, MARKER_PARENT};
pub const TASK_KIND: Kind = Kind::GitIssue; pub const TASK_KIND: Kind = Kind::GitIssue;
pub const PROCEDURE_KIND_ID: u16 = 1639; pub const PROCEDURE_KIND_ID: u16 = 1639;
@ -82,21 +83,33 @@ pub(crate) fn build_prop(
) )
} }
/// Expects sanitized input /// Return Hashtags embedded in the string.
pub(crate) fn extract_hashtags(input: &str) -> impl Iterator<Item=Tag> + '_ {
input.split_ascii_whitespace()
.filter(|s| s.starts_with('#'))
.map(|s| s.trim_start_matches('#'))
.map(to_hashtag)
}
/// Extracts everything after a ": " as a list of tags.
///
/// Expects sanitized input.
pub(crate) fn extract_tags(input: &str) -> (&str, Vec<Tag>) { pub(crate) fn extract_tags(input: &str) -> (&str, Vec<Tag>) {
match input.split_once(": ") { match input.split_once(": ") {
None => (input, vec![]), None => (input, extract_hashtags(input).collect_vec()),
Some(s) => { Some((name, tags)) => {
let tags = s let tags = extract_hashtags(name)
.1 .chain(tags.split_ascii_whitespace().map(to_hashtag))
.split_ascii_whitespace()
.map(|t| Hashtag(t.to_string()).into())
.collect(); .collect();
(s.0, tags) (name, tags)
} }
} }
} }
fn to_hashtag(tag: &str) -> Tag {
Hashtag(tag.to_string()).into()
}
fn format_tag(tag: &Tag) -> String { fn format_tag(tag: &Tag) -> String {
match tag.as_standardized() { match tag.as_standardized() {
Some(TagStandard::Event { Some(TagStandard::Event {
@ -123,3 +136,9 @@ pub(crate) fn is_hashtag(tag: &Tag) -> bool {
.is_some_and(|letter| letter.character == Alphabet::T) .is_some_and(|letter| letter.character == Alphabet::T)
} }
#[test]
fn test_extract_tags() {
assert_eq!(extract_tags("Hello from #mars with #greetings: yeah done-it"),
("Hello from #mars with #greetings", ["mars", "greetings", "yeah", "done-it"].into_iter().map(to_hashtag).collect()))
}