diff options
| -rw-r--r-- | internal/api/model/status.go | 13 | ||||
| -rw-r--r-- | internal/api/model/statuscontext.go | 17 | ||||
| -rw-r--r-- | internal/processing/status/context.go | 106 | ||||
| -rw-r--r-- | internal/typeutils/internaltofrontend_test.go | 2 | ||||
| -rw-r--r-- | web/source/css/thread.css | 9 | ||||
| -rw-r--r-- | web/template/thread.tmpl | 39 | 
6 files changed, 87 insertions, 99 deletions
diff --git a/internal/api/model/status.go b/internal/api/model/status.go index 00be868f1..a9c668565 100644 --- a/internal/api/model/status.go +++ b/internal/api/model/status.go @@ -126,8 +126,17 @@ type WebStatus struct {  	// display this status in the web view.  	Indent int -	// This status is the first status after -	// the "main" thread, so it and everything +	// This status is the last visible status +	// in the main thread, so everything below +	// can be considered "replies". +	ThreadLastMain bool + +	// This status is the one around which +	// the thread context was constructed. +	ThreadContextStatus bool + +	// This status is the first visibile status +	// after the "main" thread, so it and everything  	// below it can be considered "replies".  	ThreadFirstReply bool  } diff --git a/internal/api/model/statuscontext.go b/internal/api/model/statuscontext.go index 205672dc8..f2519c0a3 100644 --- a/internal/api/model/statuscontext.go +++ b/internal/api/model/statuscontext.go @@ -29,15 +29,16 @@ type ThreadContext struct {  }  type WebThreadContext struct { -	// Parents in the thread. -	Ancestors []*WebStatus `json:"ancestors"` - -	// Children in the thread. -	Descendants []*WebStatus `json:"descendants"` +	// Status around which this +	// thread ctx was constructed. +	Status *WebStatus -	// The status around which the ancestors -	// + descendants context was constructed. -	Status *WebStatus `json:"-"` +	// Ordered slice of statuses +	// for rendering in template. +	// +	// Includes ancestors, target +	// status, and descendants. +	Statuses []*WebStatus  	// Total length of  	// the main thread. diff --git a/internal/processing/status/context.go b/internal/processing/status/context.go index 4271bd233..013cf4827 100644 --- a/internal/processing/status/context.go +++ b/internal/processing/status/context.go @@ -400,8 +400,7 @@ func (p *Processor) WebContextGet(  	// Start preparing web context.  	wCtx := &apimodel.WebThreadContext{ -		Ancestors:   make([]*apimodel.WebStatus, 0, len(iCtx.ancestors)), -		Descendants: make([]*apimodel.WebStatus, 0, len(iCtx.descendants)), +		Statuses: make([]*apimodel.WebStatus, 0, len(wholeThread)),  	}  	var ( @@ -415,72 +414,70 @@ func (p *Processor) WebContextGet(  		// ie., who created first post in the thread.  		contextAcctID = wholeThread[0].AccountID -		// Position of target status in wholeThread, -		// we put it on top of ancestors. -		targetStatusIdx = len(iCtx.ancestors) - -		// Position from which we should add -		// to descendants and not to ancestors. -		descendantsIdx = targetStatusIdx + 1 -  		// Whether we've reached end of "main"  		// thread and are now looking at replies.  		inReplies bool -		// Index in wholeThread where -		// the "main" thread ends. +		// Index in wholeThread +		// where replies begin.  		firstReplyIdx int  		// We should mark the next **VISIBLE**  		// reply as the first reply. -		markNextVisibleAsReply bool +		markNextVisibleAsFirstReply bool  	)  	for idx, status := range wholeThread {  		if !inReplies { -			// Haven't reached end -			// of "main" thread yet. -			// -			// First post in wholeThread can't -			// be a self reply, so ignore it. -			// -			// That aside, first non-self-reply -			// in wholeThread means the "main" -			// thread is now over. -			if idx != 0 && !isSelfReply(status, contextAcctID) { -				// Jot some stuff down. -				firstReplyIdx = idx +			// Check if we've reached replies +			// by looking for the first status +			// that's not a self-reply, ie., +			// not a post in the "main" thread. +			switch { +			case idx == 0: +				// First post in wholeThread can't +				// be a self reply anyway because +				// it (very likely) doesn't reply +				// to anything, so ignore it. + +			case !isSelfReply(status, contextAcctID): +				// This is not a self-reply, which +				// means it's a reply from another +				// account. So, replies start here.  				inReplies = true -				markNextVisibleAsReply = true +				firstReplyIdx = idx +				markNextVisibleAsFirstReply = true  			}  		}  		// Ensure status is actually -		// visible to just anyone. +		// visible to just anyone, and +		// hide / don't include it if not.  		v, err := p.filter.StatusVisible(ctx, nil, status)  		if err != nil || !v { -			// Skip this one.  			if !inReplies { +				// Main thread entry hidden.  				wCtx.ThreadHidden++  			} else { +				// Reply hidden.  				wCtx.ThreadRepliesHidden++  			}  			continue  		} -		// Prepare status to add to thread context. -		apiStatus, err := p.converter.StatusToWebStatus(ctx, status) +		// Prepare visible status to add to thread context. +		webStatus, err := p.converter.StatusToWebStatus(ctx, status)  		if err != nil {  			continue  		} -		if markNextVisibleAsReply { +		if markNextVisibleAsFirstReply {  			// This is the first visible  			// "reply / comment", so the  			// little "x amount of replies"  			// header should go above this. -			apiStatus.ThreadFirstReply = true -			markNextVisibleAsReply = false +			webStatus.ThreadFirstReply = true +			markNextVisibleAsFirstReply = false  		}  		// If this is a reply, work out the indent of @@ -491,59 +488,47 @@ func (p *Processor) WebContextGet(  			case !ok:  				// No parent with  				// indent, start at 0. -				apiStatus.Indent = 0 +				webStatus.Indent = 0  			case isSelfReply(status, status.AccountID):  				// Self reply, so indent at same  				// level as own replied-to status. -				apiStatus.Indent = parentIndent +				webStatus.Indent = parentIndent  			case parentIndent == 5:  				// Already indented as far as we  				// can go to keep things readable  				// on thin screens, so just keep  				// parent's indent. -				apiStatus.Indent = parentIndent +				webStatus.Indent = parentIndent  			default:  				// Reply to someone else who's  				// indented, but not to TO THE MAX.  				// Indent by another one. -				apiStatus.Indent = parentIndent + 1 +				webStatus.Indent = parentIndent + 1  			}  			// Store the indent for this status. -			statusIndents[status.ID] = apiStatus.Indent +			statusIndents[status.ID] = webStatus.Indent  		} -		switch { -		case idx == targetStatusIdx: -			// This is the target status itself. -			wCtx.Status = apiStatus - -		case idx < descendantsIdx: -			// Haven't reached descendants yet, -			// so this must be an ancestor. -			wCtx.Ancestors = append( -				wCtx.Ancestors, -				apiStatus, -			) - -		default: -			// We're in descendants town now. -			wCtx.Descendants = append( -				wCtx.Descendants, -				apiStatus, -			) +		if webStatus.ID == targetStatusID { +			// This is the og +			// thread context status. +			webStatus.ThreadContextStatus = true +			wCtx.Status = webStatus  		} + +		wCtx.Statuses = append(wCtx.Statuses, webStatus)  	}  	// Now we've gone through the whole  	// thread, we can add some additional info.  	// Length of the "main" thread. If there are -	// replies then it's up to where the replies -	// start, otherwise it's the whole thing. +	// visible replies then it's up to where the +	// replies start, else it's the whole thing.  	if inReplies {  		wCtx.ThreadLength = firstReplyIdx  	} else { @@ -553,6 +538,9 @@ func (p *Processor) WebContextGet(  	// Jot down number of hidden posts so template doesn't have to do it.  	wCtx.ThreadShown = wCtx.ThreadLength - wCtx.ThreadHidden +	// Mark the last "main" visible status. +	wCtx.Statuses[wCtx.ThreadShown-1].ThreadLastMain = true +  	// Number of replies is equal to number  	// of statuses in the thread that aren't  	// part of the "main" thread. diff --git a/internal/typeutils/internaltofrontend_test.go b/internal/typeutils/internaltofrontend_test.go index 9ad5d2c08..7bbca8ae7 100644 --- a/internal/typeutils/internaltofrontend_test.go +++ b/internal/typeutils/internaltofrontend_test.go @@ -1014,6 +1014,8 @@ func (suite *InternalToFrontendTestSuite) TestStatusToWebStatus() {    "PollOptions": null,    "Local": false,    "Indent": 0, +  "ThreadLastMain": false, +  "ThreadContextStatus": false,    "ThreadFirstReply": false  }`, string(b))  } diff --git a/web/source/css/thread.css b/web/source/css/thread.css index 4f4e3e938..e2e6ae6b7 100644 --- a/web/source/css/thread.css +++ b/web/source/css/thread.css @@ -42,6 +42,15 @@  		h2 {  			margin-right: auto;  		} + +		&.replies.hidden-only { +			/* +				No visible replies below this column +				header, so round off the bottom. +			*/ +			border-bottom-left-radius: $br; +			border-bottom-right-radius: $br; +		}  	}  	.status { diff --git a/web/template/thread.tmpl b/web/template/thread.tmpl index 8b4aa2248..0cf9ecb05 100644 --- a/web/template/thread.tmpl +++ b/web/template/thread.tmpl @@ -20,7 +20,7 @@  {{- define "repliesSummary" -}}      {{- if .context.ThreadRepliesShown -}}          {{- if .context.ThreadRepliesHidden -}} -            {{- if eq .context.ThreadReplies 1 -}} +            {{- if eq .context.ThreadRepliesShown 1 -}}                  {{- /* Some replies are hidden. */ -}}                  {{ .context.ThreadRepliesShown }} visible reply              {{- else if gt .context.ThreadRepliesShown 1 -}} @@ -35,6 +35,8 @@                  {{ .context.ThreadReplies }} replies              {{- end -}}          {{- end -}} +    {{- else -}} +        {{- .context.ThreadRepliesHidden }} {{ if eq .context.ThreadRepliesHidden 1 }}reply{{ else }}replies{{ end }} hidden or not public      {{- end -}}  {{- end -}} @@ -60,7 +62,7 @@  {{- with . }}  </section>  <section class="thread thread-replies" aria-labelledby="replies" open> -    <div class="col-header replies"> +    <div class="col-header replies{{- if not .context.ThreadRepliesShown }} hidden-only{{- end -}}">          <h2 id="replies">{{- template "repliesSummary" . -}}</h2>          <a href="#thread-summary">back to top</a>      </div> @@ -77,41 +79,18 @@              {{- end }}          </div> -        {{- range $thisStatus := .context.Ancestors }} -        {{- if $thisStatus.ThreadFirstReply }} -        {{- include "repliesStart" $ | indent 1 }} -        {{- end }} +        {{- range $status := .context.Statuses }}          <article -            class="status{{- if $thisStatus.Indent }} indent-{{ $thisStatus.Indent }}{{- end -}}" -            {{- includeAttr "status_attributes.tmpl" $thisStatus | indentAttr 3 }} +            class="status{{- if $status.ThreadContextStatus }} expanded{{- end -}}{{- if $status.Indent }} indent-{{ $status.Indent }}{{- end -}}" +            {{- includeAttr "status_attributes.tmpl" $status | indentAttr 3 }}          > -            {{- include "status.tmpl" $thisStatus | indent 3 }} +            {{- include "status.tmpl" $status | indent 3 }}          </article> -        {{- end }} - -        {{- with $thisStatus := .context.Status }} -        {{- if $thisStatus.ThreadFirstReply }} +        {{- if and $status.ThreadLastMain $.context.ThreadReplies }}          {{- include "repliesStart" $ | indent 1 }}          {{- end }} -        <article -            class="status expanded{{- if $thisStatus.Indent }} indent-{{ $thisStatus.Indent }}{{- end -}}" -            {{- includeAttr "status_attributes.tmpl" $thisStatus | indentAttr 3  }} -        > -            {{- include "status.tmpl" $thisStatus | indent 3 }} -        </article>          {{- end }} -        {{- range $thisStatus := .context.Descendants }} -        {{- if $thisStatus.ThreadFirstReply }} -        {{- include "repliesStart" $ | indent 1 }} -        {{- end }} -        <article -            class="status{{- if $thisStatus.Indent }} indent-{{ $thisStatus.Indent }}{{- end -}}" -            {{- includeAttr "status_attributes.tmpl" $thisStatus | indentAttr 3 }} -        > -            {{- include "status.tmpl" $thisStatus | indent 3 }} -        </article> -        {{- end }}      {{- if .context.ThreadReplies }}      </section>      {{- end }}  | 
