/- tp=trill-post, tlonc=tlon-channels, *boke, contact /+ sr=sortug, ui=trill-ui, const=constants |% ++ user-profile |= [u=@p =bowl:gall] ^- res:contact =/ io ~(. io:sr bowl) =/ has-contacts .^(? %gu (weld (scry-pad:io %contacts) /$)) =/ has-whom .^(? %gu (weld (scry-pad:io %whom) /$)) =/ tact ?. has-contacts ~ =/ rolo (scry:io %contacts /all rolodex:contact) =/ utact (~(get by rolo) u) =/ prof ?~ utact ~ for.u.utact ?~ prof ~ ?~ con.prof ~ (some con.prof) =/ whom ?. has-whom ~ =/ whoms (scry:io %whom /1/contacts/mars whoms:contact) (~(get by whoms) [%.y u]) =/ res [u tact whom] res ++ flatten-fn |= fn=full-node:tp ^- (list post:tp) :: ~> %bout.[0 %flattening] =/ child-list (tap:form:tp children.fn) :- p.fn :: =/ l %+ turn child-list |= [* f=full-node:tp] p.f =/ flist=(list post:tp) =| l=(list post:tp) |- ?~ child-list l =/ child=full-node:tp +.i.child-list =/ nl (weld l (flatten-fn child)) $(child-list t.child-list, l nl) %+ sort flist |= [a=post:tp b=post:tp] (gth id.b id.a) ++ get-children-page |= [fn=full-node:tp r=page-req:tp] ^- spage:tp =/ l (tap:form:tp children.fn) =| p=spage:tp |- ?~ l %= p p %+ sort p.p |= [a=post:tp b=post:tp] (gth id.b id.a) == =/ node=full-node:tp val.i.l =/ id id.p.node ?. (page-cond id count.p r) $(l t.l) :: TODO mmm can i exit here =/ subpage (get-children-page node r) =/ new-posts=(list post:tp) p.subpage =/ oldest ?~ older.p older.subpage ?: (lth id u.older.p) older.subpage older.p =/ newest ?~ newer.p newer.subpage ?: (gth id u.newer.p) newer.subpage newer.p %= $ p.p (weld p.p [p.node new-posts]) older.p oldest newer.p newest count.p +(count.p) l t.l == ++ get-siblings-page |= fn=full-node:tp ^- spage:tp =/ pg (get-children-page fn [~ ~ thread-page-size:const]) =/ ind (find ~[p.fn] p.pg) ?~ ind *spage:tp =/ start=@ ?: (lth u.ind thread-page-size:const) 0 (sub u.ind thread-page-size:const) %= pg p (swag [start thread-page-size:const] p.pg) == :: ++ get-siblings-page-2 :: |= l=(list post:tp) ^- spage:tp :: =/ pg (get-children-page fn [~ ~ thread-page-size:const]) :: =/ ind (find ~[p] p.pg) :: ?~ ind *spage:tp :: =/ start=@ ?: (lth u.ind thread-page-size:const) 0 (sub u.ind thread-page-size:const) :: %= pg :: p (swag [start thread-page-size:const] p.pg) :: == ++ flatten-fn-2 |= fn=full-node:tp ^- (list post:tp) :: ~> %bout.[0 %flattening-2] =/ child-list (tap:form:tp children.fn) :- p.fn %- sort :_ |= [a=post:tp b=post:tp] (gth id.b id.a) |- ^- (list post:tp) ?~ child-list ~ %+ weld (flatten-fn-2 +.i.child-list) $(child-list t.child-list) ++ common-thread |= [p=post:tp f=gfeed:tp] ^- @ud =/ pid thread.p =/ l (tap:gorm:tp f) %- lent %+ skim l |= [k=pid:tp v=post:tp] .= thread.v pid :: ++ flatten-4 :: |= p=post:tp ^- (list pid:tp) :: ~> %bout.[0 %flattening-4] :: =/ child-list ~(tap in children.fn) :: =/ =pid:tp [author.p id.p] :: :- pid :: |- ^- (list post:tp) :: ?~ child-list ~ :: =/ child-post (~(get by feed) pid) :: %+ weld (flatten-fn-p child-post) :: $(child-list t.child-list) :: +$ ll (list pid:tp) :: ++ flatten-raw :: |= [l=ll acc=ll] ^- ll :: ?~ l acc :: $(l t.l, acc [i.l acc]) ++ node-to-full-fake |= p=post:tp ^- full-node:tp =/ fake-children=full-graph:tp %- ~(rep in children.p) |= [=pid:tp acc=full-graph:tp] (put:form:tp acc pid *full-node:tp) :- p fake-children ++ node-to-full |= [p=post:tp f=gfeed:tp] ^- full-node:tp =/ children (~(del in children.p) [author.p id.p]) :: else infinite loop. not that it should happen at all :- p (convert-children children f) ++ convert-children |= [children=(set pid:tp) f=gfeed:tp] ^- full-graph:tp %- ~(rep in children) |= [=pid:tp acc=full-graph:tp] =/ n (get:gorm:tp f pid) ?~ n ~& child-not-found=pid acc =/ full-node (node-to-full u.n f) (put:form:tp acc pid full-node) ++ sanitize |= c=content-list:tp ^- ? %+ roll c |= [i=block:tp acc=_&] ?. ?=(%paragraph -.i) acc %+ roll p.i |= [ii=inline:tp iacc=_acc] ?. ?=(%link -.ii) iacc ?~ (de-purl:html href.ii) .n .y ++ block-size |= =block:tp ^- @ud ?- -.block %tasklist 0 :: TODO %paragraph (inline-size p.block) %blockquote (inline-size p.block) %heading (lent (trip p.block)) %media (media-size media.block) %codeblock ?: (gth (lent (trip lang.block)) 400) 10.000 (lent (trip code.block)) %eval (lent (trip hoon.block)) %ref ?: (gth (lent (trip app.block)) 400) 10.000 (roll path.block |=([i=@t a=@] (add a (lent (trip i))))) %json ?: (gth (lent (trip content.block)) 5.000) 10.000 ?: (gth (lent (trip origin.block)) 1.000) 10.000 0 %list %+ roll p.block |= [c=content-list:tp a=@ud] %+ add a %+ roll c |= [b=block:tp aa=@ud] (add aa (block-size b)) :: %table :: %+ roll rows.block |= [i=(list contents:tp) a=@] :: =/ inner-count=@ :: %+ roll i |= [ii=contents:tp ia=@] :: (add ia (post-size ii)) :: (add inner-count a) == ++ post-size |= c=content-list:tp =| count=@ |- ?~ c count =/ lc=@ (block-size i.c) $(c t.c, count (add count lc)) ++ inline-token-size |= i=inline:tp ^- @ud ?+ -.i (lent (trip p.i)) %break 1 %date 1 %note (add (met 3 id.i) 10):: TODO) %ship (lent (trip (scot %p p.i))) %ruby (lent (trip p.i)) %link ?: (gth (lent (trip href.i)) 400) 10.000 :: to prevent hacking through a huge href string (lent (trip show.i)) == ++ reduce-inline |= [i=inline:tp chars=@ud] ^+ i ?- -.i %break i %date i %note i :: TODO %ship [%text (crip (weld (scag chars (trip (scot %ud p.i))) "..."))] %ruby i(p (crip (scag chars (trip p.i)))) %link i(show (crip (scag chars (trip show.i)))) %bold [-.i (crip (scag chars (trip +.i)))] %codespan [-.i (crip (scag chars (trip +.i)))] %italic [-.i (crip (scag chars (trip +.i)))] %strike [-.i (crip (scag chars (trip +.i)))] %sub [-.i (crip (scag chars (trip +.i)))] %sup [-.i (crip (scag chars (trip +.i)))] %text [-.i (crip (weld (scag chars (trip +.i)) "..."))] %underline [-.i (crip (scag chars (trip +.i)))] == ++ inline-size |= l=(list inline:tp) ^- @ =| count=@ud |- ?~ l count =/ lc=@ud (inline-token-size i.l) $(l t.l, count (add count lc)) ++ media-size |= =media:tp ^- @ ?- -.media %video (lent (trip p.media)) %audio (lent (trip p.media)) %images %+ roll p.media |= [[url=@t caption=@t] a=@] %+ add a (add (met 3 url) (met 3 caption)) == ++ search |= [q=@t p=post:tp] ^- ? =/ latest=content-list:tp val:head:(pop:corm:tp contents.p) ?| (in-tags ~(tap in tags.p) q) (in-blocks latest q) == ++ in-tags |= [tl=(list @t) q=@t] ^- ? |- ?~ tl .n ?: (contains i.tl q) .y $(tl t.tl) ++ in-blocks |= [bl=content-list:tp q=@t] ^- ? |- ?~ bl .n ?: (in-block i.bl q) .y $(bl t.bl) ++ in-block |= [i=block:tp q=@t] ^- ? ?- -.i %paragraph (in-inline p.i q) %blockquote (in-inline p.i q) %heading (contains p.i q) %codeblock (contains code.i q) %eval (contains hoon.i q) %json (contains content.i q) %media (in-media media.i q) %ref %| :: TODO :: %table %| :: TODO %tasklist .n :: TODO %list |- ?~ p.i .n ?: (in-blocks i.p.i q) .y $(p.i t.p.i) == ++ in-media |= [=media:tp q=@t] ^- ? ?. ?=(%images -.media) (contains p.media q) =/ l p.media |- ?~ l .n ?: ?| (contains url.i.l q) (contains caption.i.l q) == .y $(l t.l) ++ in-inline |= [l=(list inline:tp) q=@t] ^- ? |- ?~ l .n =/ i i.l =/ has ?+ -.i (contains p.i q) %break %| %ship (contains (scot %p p.i) q) %date .n :: TODO %note ?|((contains id.i q) (in-inline text.i q)) %link ?|((contains href.i q) (contains show.i q)) %ruby ?|((contains p.i q) (contains q.i q)) == ?: has .y $(l t.l) ++ is-my-reply |= [p=post:tp r=post:tp our=@p] ^- ? ?~ parent.r .n ?& .=(author.r our) !.=(author.p our) == ++ is-thread-child |= [p=post:tp r=post:tp our=@p] ^- ? ?~ parent.r .n ?& .=(author.r our) .=(author.p our) == ++ houyi |= children=full-graph:tp ^- @ud ?~ children 0 =/ lst (tap:form:tp children) %+ add (lent lst) %+ roll lst |= [[=pid:tp n=full-node:tp] acc=@ud] (add acc (houyi children.n)) ++ latest-contents |= cm=content-map:tp ^- content-list:tp =/ latest (pry:corm:tp cm) ?~ latest ~ +.u.latest :: ++ abbreviate-post |= [cm=content-map:tp max-chars=@ud] ^- content-list:tp =/ c (latest-contents cm) :: we reduce the list of blocks. We count how many characters are there in each block. :: If the block fits in our count, we insert the block in the filtered list. :: If not, we cut the content of the box until it does. =/ ret=content-list:tp =< +< %^ spin c [bl=*content-list:tp available=max-chars] |= [b=block:tp [bl=_c available=@ud]] :: We must return the same data type as the input :: We don't want to map on the individual block so return as is :- b :: The state tho is what we're playing with. :: We pass the current block and the available char count to another function =/ cut=[(unit block:tp) @ud] (cut-block b available) :: That function checks whether the block fits within the available count. :: It returns a maybe block and the remaining count :: If null, we return the list as is ?~ -.cut [bl available] :: If we get a block back, we add that to our block list, and update the available count [[u.-.cut bl] +.cut] (flop ret) ++ cut-block :: now let's go inside the block |= [b=block:tp available=@ud] ^- [(unit block:tp) @ud] ?+ -.b [~ 0] :: :: This we can cut %paragraph =/ inlines (cut-inlines p.b available) ?~ -.inlines [~ available] :- `[-.b -.inlines] +.inlines :: :: these must go whole or nothing :: :: %blockquote :: :: %heading :: :: %list :: :: %media :: :: %eval :: :: %poll :: :: %ref :: :: %json :: :: %table == ++ cut-inlines |= [li=(list inline:tp) available=@ud] ^+ [li available] ?: .=(0 available) [~ 0] :: We spin again =/ ret=[_li @ud] =/ initial-state [*(list inline:tp) available] =< + %^ spin li initial-state |= [l=inline:tp [nl=_li available=@ud]] :: Again we're not mapping over the tokens, just mutating an internal state :- l :: If no more chars available we return of course ?: .=(0 available) [nl available] :: We look at the size of the current token =/ size (inline-token-size l) :: If the size is smaller than available, we add to new list, and substract from available ?: (lte size available) [[l nl] (sub available size)] :: If size is bigger than available we reduce the token, insert to list, set avaibable as 0 =/ reduced (reduce-inline l available) [[reduced nl] 0] [(flop -.ret) +.ret] :: :: :: search ++ text-search |= [q=@t length=@ud p=post:tp case=?] ^- tape :: ~> %bout.[0 %text-search] =/ t (content-to-md:ui contents.p) :: ~2020.7.31..23.51.21 :: =/ hstk ?: case t (cass t) :: =/ nedl ?: case (trip q) (cass (trip q)) :: =/ i (find nedl hstk) :: ?~ i "" :: =/ start ?: (lte u.i length) 0 (sub u.i length) :: ?: .=(start 0) :: "{(swag [start (mul 2 length)] t)}..." :: "...{(swag [start (mul 2 length)] t)}..." "" ++ contains |= [container=cord query=cord] ^- ? ?~ (find (trip query) (trip container)) %| %& :: ++ text-search-ind |= [q=@t length=@ud p=post:tp case=?] ^- @t :: ~> %bout.[0 %text-search-ind] ?~ contents.p '' =/ bl=(list block:tp) val:head:(pop:corm:tp contents.p) =| ob=(list block:tp) |- ?~ bl '' :: TODO proper counts =/ i i.bl =/ r=(unit completion) ?+ -.i ~ %paragraph (inline-ind p.i q length case) %blockquote (inline-ind p.i q length case) :: :: %list (from-inline p.i.bl q case) %heading (cfind-index:sr q p.i length .n) %codeblock (cfind-index:sr q code.i length .n) %eval (cfind-index:sr q hoon.i length .n) %json (cfind-index:sr q content.i length .n) :: %media (in-media2 media.i q) :: %ref snippet :: TODO :: %table snippet :: TODO :: %tasklist snippet == ?~ r $(bl t.bl, ob [i.bl ob]) ?: (gte (met 3 snip.u.r) length) snip.u.r :: victory =. u.r ?. (gth left-amari.u.r 0) u.r :: go fetch stuff on the left =/ left-fill=@t (fill-up-block left-amari.u.r ob .y) =/ added (cat 3 left-fill snip.u.r) u.r(snip added, left-amari (sub left-amari.u.r (met 3 left-fill))) =. u.r ?. (gth right-amari.u.r 0) u.r :: go fetch stuff on the right =/ right-fill=@t (fill-up-block right-amari.u.r t.bl .n) =/ added (cat 3 snip.u.r right-fill) u.r(snip added, right-amari (sub right-amari.u.r (met 3 right-fill))) snip.u.r +$ completion [snip=@t left-amari=@ud right-amari=@ud] ++ inline-ind |= [l=(list inline:tp) q=@t length=@ud case=?] ^- (unit completion) =| ob=(list inline:tp) |- ?~ l ~ =/ r=(unit completion) ?+ -.i.l (cfind-index:sr q p.i.l length .n) %break ~ %date ~ :: TODO %note ~ ::TODO %ship (cfind-index:sr q (scot %p p.i.l) length .n) %link (cfind-index:sr q (cat 3 href.i.l show.i.l) length .n) %ruby (cfind-index:sr q (cat 3 p.i.l q.i.l) length .n) == ?~ r $(l t.l, ob [i.l ob]) ?: (gte (met 3 snip.u.r) length) r :: exit condition =. u.r ?. (gth left-amari.u.r 0) u.r :: go fetch stuff on the left =/ left-fill=@t (fill-up left-amari.u.r ob .y) =/ added (cat 3 left-fill snip.u.r) u.r(snip added, left-amari (sub left-amari.u.r (met 3 left-fill))) =. u.r ?. (gth right-amari.u.r 0) u.r :: go fetch stuff on the right =/ right-fill=@t (fill-up right-amari.u.r t.l .n) =/ added (cat 3 snip.u.r right-fill) u.r(snip added, right-amari (sub right-amari.u.r (met 3 right-fill))) r :: ++ fill-up-block |= [length=@ud l=(list block:tp) backwards=?] ^- @t =| acc=@t |- ?~ l acc ?: ?=(%paragraph -.i.l) (fill-up length p.i.l backwards) ?: ?=(%blockquote -.i.l) (fill-up length p.i.l backwards) =/ string=@t ?+ -.i.l '' %heading p.i.l %codeblock code.i.l %eval hoon.i.l %json content.i.l :: %media (in-media2 media.i q) :: %ref snippet :: TODO :: %table snippet :: TODO :: %tasklist snippet :: :: %list (from-inline p.i.bl q case) == =. acc ?: backwards =/ end (met 3 string) =/ start ?: (lth end length) 0 (sub end length) =/ piece=@t (cut 3 [start end] string) (cat 3 piece acc) :: forwards =/ piece=@t (cut 3 [0 length] string) (cat 3 acc piece) =/ size (met 3 acc) ?: .=(size length) acc :: exit condition ?: (gte size length) '' :: bug $(l t.l, length (sub length size)) ++ fill-up |= [length=@ud l=(list inline:tp) backwards=?] ^- @t =| acc=@t |- ?~ l acc =/ string=@t ?+ -.i.l p.i.l %break '' %date '' :: TODO %note '' ::TODO %ship (scot %p p.i.l) %link (cat 3 href.i.l show.i.l) %ruby (cat 3 p.i.l q.i.l) == =. acc ?: backwards =/ end (met 3 string) =/ start ?: (lth end length) 0 (sub end length) =/ piece=@t (cut 3 [start end] string) (cat 3 piece acc) :: forwards =/ piece=@t (cut 3 [0 length] string) (cat 3 acc piece) =/ size (met 3 acc) ?: .=(size length) acc :: exit condition ?: (gth size length) '' :: this should never happen $(l t.l, length (sub length size)) :: ++ text-search2 |= [q=@t length=@ud p=post:tp case=?] ^- @t ~> %bout.[0 %text-search] ?~ contents.p '' =/ bl=(list block:tp) val:head:(pop:corm:tp contents.p) =| snippet=@t |- ?~ bl snippet :: TODO proper counts ?: (gth (met 3 snippet) length) snippet =/ i i.bl =/ ns ?+ -.i snippet %paragraph (from-inline p.i q length case) :: %blockquote (from-inline p.i q length case) :: :: %list (from-inline p.i.bl q case) :: %heading (cfind:sr q p.i .n) :: %codeblock (cfind:sr q code.i .n) :: %eval (cfind:sr q hoon.i .n) :: %json (cfind:sr q content.i .n) :: %media (in-media2 media.i q) :: %ref snippet :: TODO :: %table snippet :: TODO :: %tasklist snippet == $(bl t.bl, snippet (cat 3 snippet ns)) ++ from-inline |= [l=(list inline:tp) q=@t length=@ud case=?] ^- @t =| snippet=@t |- ?~ l snippet ?: (gth (met 3 snippet) length) snippet =/ r ?+ -.i.l (cfindi:sr q p.i.l .n) %break '\0a' %date .n :: TODO %note .n ::TODO %ship (cfindi:sr q (scot %p p.i.l) .n) %link (cat 3 (cfindi:sr q href.i.l .n) (cfindi:sr q show.i.l .n)) %ruby (cat 3 (cfindi:sr q p.i.l .n) (cfindi:sr q q.i.l .n)) == $(l t.l, snippet (cat 3 snippet r)) :: ++ search2 :: |= [q=@t p=post:tp] ^- ? :: ?~ contents.p .n :: =/ latest=content-list:tp val:head:(pop:corm:tp contents.p) :: =/ in-tags %+ roll ~(tap in tags.p) |= [i=cord a=_|] :: ?: (cfind:sr q i .n) %& a :: =/ in-blocks %+ roll latest |= [i=block:tp a=_|] :: ?: ?- -.i :: %paragraph (in-inline2 p.i q) :: %blockquote (in-block p.i q) :: %list (in-inline2 p.i q) :: %heading (cfind:sr q p.i .n) :: %codeblock (cfind:sr q code.i .n) :: %eval (cfind:sr q hoon.i .n) :: %json (cfind:sr q content.i .n) :: %media (in-media2 media.i q) :: %ref %| :: TODO :: %table %| :: TODO :: %tasklist .n :: == %& a :: ?| in-tags in-blocks == ++ in-media2 |= [=media:tp q=@t] ^- ? ?. ?=(%images -.media) (cfind:sr q p.media .n) %+ roll p.media |= [[url=cord caption=cord] a=_|] ?: (cfind:sr q url .n) %& a :: ++ in-inline2 :: |= [l=(list inline:tp) q=@t] ^- ? :: |- :: ?~ l .n :: =/ i i.l :: =/ r=? :: ?+ -.i (cfind:sr q p.i .n) :: %break .n :: %date .n :: %note .n :: %ship (cfind:sr q (scot %p p.i) .n) :: %link ?|((cfind:sr q href.i .n) (cfind:sr q show.i .n)) :: %ruby ?|((cfind:sr q p.i .n) (cfind:sr q q.i .n)) :: == :: ?| r $(l t.l) == :: ++ page-cond |= [id=@da current=@ud r=page-req:tp] ^- ? =/ need-more (lth current count.r) ?~ newer.r :: newest not bound ?~ older.r :: neither oldest or newest is bound need-more :: oldest is bound, newest isn't ?& need-more (lth id u.older.r) == :: newest bound ?~ older.r :: newest is bound, oldest isn't ?& need-more (gth id u.newer.r) == :: both are bound ?&(need-more (lth id u.older.r) (gth id u.newer.r)) ++ get-post-page |= [feed=gfeed:tp req=page-req:tp] ^- page:tp =/ from-bottom=? ?& ?=(%~ older.req) ?!(?=(%~ newer.req)) == =/ l ?. from-bottom (tap:gorm:tp feed) (flop (tap:gorm:tp feed)) =/ res %+ roll l |= [[=pid:tp =post:tp] a=[p=page:tp max=@da min=@da]] =/ id id.pid ?^ parent.post a =/ max ?: (gth id max.a) id max.a =/ min ?: ?|((lth id min.a) .=(min.a *@da)) id min.a :_ [max min] =/ condition=? (page-cond id count.p.a req) ?. condition p.a =/ posts [(node-to-full post feed) p.p.a] :: =/ oldest ?~ older.p.a `id ?: (lth id u.older.p.a) `id older.p.a =/ newest ?~ newer.p.a `id ?: (gth id u.newer.p.a) `id newer.p.a [posts newest oldest +(count.p.a)] :: TODO arg gotta figure this out =/ o ?: .=(older.p.res `min.res) ~ older.p.res :: ?: (lth count.res count.req) ~ =/ n ?: .=(newer.p.res `max.res) ~ newer.p.res =/ poasts ?. from-bottom (flop p.p.res) p.p.res [poasts n o count.p.res] :: ++ basic-filter :: |= [=feed:tp req=page-req:tp filter=$-(post:tp ?)] :: |= [[=id:tp =post:tp] a=spage:tp] :: ?. (filter post) a :: =/ posts [post p.a] :: =/ oldest ?~ older.a `id :: ?: (lth id u.older.a) `id older.a :: [posts newer.r oldest +(count.a)] :: TODO spage or page... ++ get-filtered-post-page-full |= [feed=gfeed:tp req=page-req:tp filter=$-(post:tp ?)] ^- page:tp =/ from-bottom=? ?& ?=(%~ older.req) ?!(?=(%~ newer.req)) == =/ l ?. from-bottom (tap:gorm:tp feed) (flop (tap:gorm:tp feed)) =/ res %+ roll l |= [[=pid:tp =post:tp] a=[p=page:tp max=@da min=@da]] =/ id id.pid ?. (filter post) a =/ condition=? (page-cond id count.p.a req) =/ max ?: (gth id max.a) id max.a =/ min ?: ?|((lth id min.a) .=(min.a *@da)) id min.a :_ [max min] ?. condition p.a =/ posts [(node-to-full post feed) p.p.a] :: =/ oldest ?~ older.p.a `id ?: (lth id u.older.p.a) `id older.p.a =/ newest ?~ newer.p.a `id ?: (gth id u.newer.p.a) `id newer.p.a [posts newest oldest +(count.p.a)] :: TODO arg gottaa figure this out =/ o ?: .=(older.p.res `min.res) ~ older.p.res :: ?: (lth count.res count.req) ~ =/ n ?: .=(newer.p.res `max.res) ~ newer.p.res =/ poasts ?. from-bottom (flop p.p.res) p.p.res [poasts n o count.p.res] ++ get-filtered-post-page |= [feed=gfeed:tp req=page-req:tp filter=$-(post:tp ?)] ^- spage:tp =/ from-bottom=? ?& ?=(%~ older.req) ?!(?=(%~ newer.req)) == =/ l ?. from-bottom (tap:gorm:tp feed) (flop (tap:gorm:tp feed)) =/ res %+ roll l |= [[=pid:tp =post:tp] a=[p=spage:tp max=@da min=@da]] =/ id id.pid ?. (filter post) a =/ condition=? (page-cond id count.p.a req) =/ max ?: (gth id max.a) id max.a =/ min ?: ?|((lth id min.a) .=(min.a *@da)) id min.a :_ [max min] ?. condition p.a =/ posts [post p.p.a] :: =/ oldest ?~ older.p.a `id ?: (lth id u.older.p.a) `id older.p.a =/ newest ?~ newer.p.a `id ?: (gth id u.newer.p.a) `id newer.p.a [posts newest oldest +(count.p.a)] :: TODO arg gottaa figure this out =/ o ?: .=(older.p.res `min.res) ~ older.p.res :: ?: (lth count.res count.req) ~ =/ n ?: .=(newer.p.res `max.res) ~ newer.p.res =/ poasts ?. from-bottom (flop p.p.res) p.p.res [poasts n o count.p.res] :: ++ get-tag-page :: |= [feed=gfeed:tp tt=tags-table l=(list @t) r=page-req:tp] ^- page:tp :: ~> %bout :: =/ pids %+ roll l |= [i=@t a=(list pid:tp)] =/ ps (~(get by tt) i) :: ?~ ps a (weld u.ps a) :: =/ filter |= =post:tp (~(has in (sy pids)) [author.post id.post]) :: (get-filtered-post-page-full feed r filter) :: ++ pcond :: |= [id=@da r=page-req:tp] ^- ? :: ?~ older.r :: ?~ newer.r .y :: (gth id u.newer.r) :: ?~ newer.r :: (lth id u.older.r) :: ?& (lth id u.older.r) (gth id u.newer.r) == :: ++ get-tag-page-2 :: |= [feed=gfeed:tp tt=tags-table l=(list @t) r=page-req:tp] ^- page:tp :: =/ =pid-graph:tp :: ~> %bout :: %+ roll l |= [i=@t a=pid-graph:tp] :: =/ pids-by-tag (~(get by tt) i) :: ?~ pids-by-tag a =/ pl (flop u.pids-by-tag) :: |- :: ?~ pl a :: ?. (pcond id.i.pl r) $(pl t.pl) :: %= $ :: a (put:porm:tp a id.i.pl ship.i.pl) :: pl t.pl :: == :: =/ top (pry:porm:tp pid-graph) :: =/ tom (ram:porm:tp pid-graph) :: =/ max ?~ top ~ `-.u.top :: =/ min ?~ tom ~ `-.u.tom :: =/ res=page:tp :: =| =page:tp :: =/ pids (tap:porm:tp pid-graph) :: |- :: ?~ pids page :: =/ id -.i.pids :: ?: .=(count.page count.r) page :: ?. (pcond id r) $(pids t.pids) :: =/ post (get:gorm:tp feed [+.i.pids id]) :: ?~ post $(pids t.pids) :: =/ np=page:tp :: =/ posts [(node-to-full u.post feed) p.page] :: =/ oldest ?~ older.page `id :: ?: (lth id u.older.page) `id older.page :: =/ newest ?~ newer.page `id :: ?: (gth id u.newer.page) `id newer.page :: [posts newest oldest +(count.page)] :: %= $ :: page np :: pids t.pids :: == :: =/ n ?: .=(max newer.res) ~ newer.res :: =/ o ?: .=(min older.res) ~ older.res :: res(newer n, older o, p (flop p.res)) :: ++ get-tag-page-3 :: |= [feed=gfeed:tp tt=tags-table l=(list @t) r=page-req:tp] ^- page:tp :: ~> %bout :: =/ empty *page:tp :: =| count=@ud :: =/ posts=(list full-node:tp) :: |- ^- (list full-node:tp) :: ?~ l ~ :: =/ pids (~(get by tt) i.l) :: ?~ pids ~ :: =/ pl (flop u.pids) :: %+ welp ^- (list full-node:tp) :: |- :: ?~ pl ~ :: ?: (gte count count.r) ~ :: ?. (pcond +.i.pl r) $(pl t.pl) :: =/ poast (get:gorm:tp feed i.pl) :: ?~ poast $(pl t.pl) :: =/ fn (node-to-full u.poast feed) :: :- fn :: $(pl t.pl, count +(count)) :: $(l t.l) :: :: :: =/ newer ~ :: =/ older ?~ posts ~ (some id:p:(rear posts)) :: [posts newer older (lent posts)] ++ tag-search |= l=(list @t) |= =post:tp ^- ? |- ?~ l .n =/ ok=? ?& (~(has in tags.post) (crip (cass (trip i.l)))) ?=(%~ parent.post) == ?: ok .y $(l t.l) ++ tag-search-old |= [l=(list @t) feed=gfeed:tp r=page-req:tp] ^- page:tp %+ roll (tap:gorm:tp feed) |= [[=pid:tp =post:tp] a=page:tp] =/ id id.pid =/ condition (page-cond id count.a r) ?. condition a =/ found =/ has .y |- ?~ l has ?& has =/ ns (~(has in tags.post) (crip (cass (trip i.l)))) $(l t.l, has ns) == =/ posts ?. found p.a :_ p.a (node-to-full post feed) =/ oldest ?~ older.a `id ?: (lth id u.older.a) `id older.a =/ count ?: .=(count.a count.r) count.r +(count.a) [posts newer.r oldest count] :: ++ search-filter-full |= [feed=gfeed:tp req=page-req:tp filter=$-(post:tp ?)] ^- page:tp =/ from-bottom=? ?& ?=(%~ older.req) ?!(?=(%~ newer.req)) == =/ l ?. from-bottom (tap:gorm:tp feed) (flop (tap:gorm:tp feed)) =/ res %+ roll l |= [[=pid:tp =post:tp] a=[p=page:tp max=@da min=@da]] =/ id id.pid ?. (filter post) a =/ condition=? (page-cond id count.p.a req) =/ max ?: (gth id max.a) id max.a =/ min ?: ?|((lth id min.a) .=(min.a *@da)) id min.a :_ [max min] ?. condition p.a =/ posts [(node-to-full post feed) p.p.a] :: =/ oldest ?~ older.p.a `id ?: (lth id u.older.p.a) `id older.p.a =/ newest ?~ newer.p.a `id ?: (gth id u.newer.p.a) `id newer.p.a [posts newest oldest +(count.p.a)] =/ o ?: .=(older.p.res `min.res) ~ older.p.res :: ?: (lth count.res count.req) ~ =/ n ?: .=(newer.p.res `max.res) ~ newer.p.res =/ poasts ?. from-bottom (flop p.p.res) p.p.res [poasts n o count.p.res] ++ search-filter |= [feed=gfeed:tp req=page-req:tp filter=$-(post:tp ?)] ^- spage:tp =/ from-bottom=? ?& ?=(%~ older.req) ?!(?=(%~ newer.req)) == =/ l ?. from-bottom (tap:gorm:tp feed) (flop (tap:gorm:tp feed)) =/ res %+ roll l |= [[=pid:tp =post:tp] a=[p=spage:tp max=@da min=@da]] =/ id id.pid ?. (filter post) a =/ condition=? (page-cond id count.p.a req) =/ max ?: (gth id max.a) id max.a =/ min ?: ?|((lth id min.a) .=(min.a *@da)) id min.a :_ [max min] ?. condition p.a =/ posts [post p.p.a] :: =/ oldest ?~ older.p.a `id ?: (lth id u.older.p.a) `id older.p.a =/ newest ?~ newer.p.a `id ?: (gth id u.newer.p.a) `id newer.p.a [posts newest oldest +(count.p.a)] =/ o ?: .=(older.p.res `min.res) ~ older.p.res :: ?: (lth count.res count.req) ~ =/ n ?: .=(newer.p.res `max.res) ~ newer.p.res =/ poasts ?. from-bottom (flop p.p.res) p.p.res [poasts n o count.p.res] :: ++ tlon-scan-to-post |= s=reference:tlonc ^- post:tp =/ np *post:tp ?: ?=(%post -.s) =/ =memo:tlonc +>-.s =/ children %- sy %+ turn (tap:on-replies:tlonc replies.+<.s) |= [id=@da reply:tlonc] [author id] %= np id sent.memo author author.memo thread [~zod sent.memo] :: TODO mmm parent ~ contents (tlon-trill-contents content.memo sent.memo) children children == :: =/ =memo:tlonc +.reply.s =/ par parent-id.-.reply.s %= np id sent.memo author author.memo thread [~zod par] :: TODO really? parent (some [~zod par]) :: TODO mmm contents (tlon-trill-contents content.memo sent.memo) == ++ tlon-trill-contents |= [l=(list verse:tlonc) =time] ^- content-map:tp =/ cl=content-list:tp %+ roll l |= [i=verse:tlonc a=content-list:tp] ?: ?=(%block -.i) :_ a (tlon-block p.i) =/ l p.i =/ nb=content-list:tp *content-list:tp =/ cl=content-list:tp |- ?~ l nb =/ nnb=content-list:tp ?: ?=(%task -.i.l) =/ task [(turn q.i.l tlon-inline) p.i.l] =/ lb (last-block nb %tasklist) =/ tl=(list task:tp) ?~ lb ~ ?. ?=(%tasklist -.u.lb) ~ p.u.lb (snoc nb [%tasklist (snoc tl task)]) ?: ?=(%blockquote -.i.l) (snoc nb [%blockquote (turn p.i.l tlon-inline)]) ?: ?=(%code -.i.l) (snoc nb [%codeblock p.i.l '']) ?: ?=(%block -.i.l) (snoc nb [%ref %channels ~zod /]) :: TODO lol :: =/ bun=(list inline:tp) ~ =/ f (flop nb) =/ inlines ?~ f bun =/ first=block:tp -.f ?. ?=(%paragraph -.first) bun p.first %+ snoc nb :- %paragraph %+ snoc inlines ?- -.i.l %italics [%italic (crip (flatten-tlon-inline p.i.l))] %bold [%bold (crip (flatten-tlon-inline p.i.l))] %strike [%strike (crip (flatten-tlon-inline p.i.l))] %inline-code [%codespan p.i.l] %ship [%ship p.i.l] %tag [%text p.i.l] %link [%link p.i.l q.i.l] %break [%break ~] == $(l t.l, nb nnb) (weld cl a) =/ g=(list [@da content-list:tp]) :~([time (flop cl)]) %+ gas:corm:tp *content-map:tp g :: ++ last-block |= [l=content-list:tp tag=$?(%paragraph %tasklist)] ^- (unit block:tp) =/ f (flop l) |- ?~ f ~ ?: .=(tag -.i.f) (some i.f) $(f t.f) ++ tlon-block |= b=block:tlonc ^- block:tp ?- -.b %image [%media %images ~[[src.b alt.b]]] %cite (tlon-cite +.b) %header [%heading (crip (flatten-tlon-inline q.b)) p.b] %listing (tlon-listing p.b) %rule [%paragraph ~] %code [%codeblock code.b lang.b] == ++ tlon-listing |= l=listing:tlonc ^- block:tp ?. ?=(%list -.l) [%paragraph (turn p.l tlon-inline)] :: ?: ?=(%tasklist p.l) :- %tasklist ~ :: TODO wtf is this%+ roll q.l :: TODO idgi what r does in this type :- %list :_ ?=(%ordered p.l) ~ :: TODO i'm tired :: :_ ~ :_ ~ %+ roll q.l tlon-listing ++ tlon-inline |= i=inline:tlonc ^- inline:tp ?@ i [%text i] ?- -.i %italics [%italic (crip (flatten-tlon-inline p.i))] %bold [%bold (crip (flatten-tlon-inline p.i))] %strike [%strike (crip (flatten-tlon-inline p.i))] %blockquote [%text (crip (weld "> " (flatten-tlon-inline p.i)))] %inline-code [%codespan p.i] %code [%codespan p.i] %ship [%ship p.i] %block [%break ~]:: [%ref %channels ~zod /] %tag [%text p.i] %link [%link p.i q.i] %task [%text ''] %break [%break ~] == ++ flatten-tlon-inline |= l=(list inline:tlonc) ^- tape %+ roll l |= [i=inline:tlonc a=tape] =/ res ?@ i (trip i) ?- -.i %italics (flatten-tlon-inline p.i) %bold (flatten-tlon-inline p.i) %strike (flatten-tlon-inline p.i) %blockquote (flatten-tlon-inline p.i) %inline-code (trip p.i) %code (trip p.i) %ship (scow %p p.i) %block (trip q.i) %tag (trip p.i) %link (trip p.i) %task (flatten-tlon-inline q.i) %break "" == " {a} {res}" ++ tlon-cite |= c=cite:tlonc :- %ref ?- -.c %chan [%channels p.q.nest.c wer.c] :: TODO is this path ok? nah needs type of channel and whatever %group [%groups p.flag.c /[q.flag.c]] %desk [%app p.flag.c wer.c] :: TODO same %bait [%groups p.grp.c wer.c] :: TODO same == :: ++ add-tag-lookup :: |= [lt=(list @t) =pid:tp table=tags-table] ^- tags-table :: %^ fold:sr lt table |= [tag=@t a=tags-table] :: =/ cur (~(get by a) tag) :: =/ nl ?~ cur :: =/ bnt *threads :: (put:torm:tp bnt pid ) :: ~[pid] [pid u.cur] :: (~(put by a) tag nl) --