classify_bookmarks.go
package calls
import (
"skraak/datafile"
)
// getFilterLabel returns the label matching the current filter, or first label if no filter.
func (s *ClassifyState) getFilterLabel(seg *datafile.Segment) *datafile.Label {
if s.Config.Filter == "" {
if len(seg.Labels) > 0 {
return seg.Labels[0]
}
return nil
}
for _, label := range seg.Labels {
if label.Filter == s.Config.Filter {
return label
}
}
return nil
}
// getOrCreateFilterLabel gets existing label or creates new one for the current filter.
func (s *ClassifyState) getOrCreateFilterLabel(seg *datafile.Segment) *datafile.Label {
label := s.getFilterLabel(seg)
if label != nil {
return label
}
// Create new label
label = &datafile.Label{
Species: "Don't Know",
Certainty: 0,
Filter: s.Config.Filter,
}
seg.Labels = append(seg.Labels, label)
s.Dirty = true
return label
}
// HasBookmark returns true if current segment has a bookmark on the filter label.
func (s *ClassifyState) HasBookmark() bool {
seg := s.CurrentSegment()
if seg == nil {
return false
}
label := s.getFilterLabel(seg)
return label != nil && label.Bookmark
}
// ToggleBookmark toggles the bookmark on the current segment's filter label.
func (s *ClassifyState) ToggleBookmark() {
seg := s.CurrentSegment()
if seg == nil {
return
}
df := s.CurrentFile()
if df == nil {
return
}
// Set reviewer
df.Meta.Reviewer = s.Config.Reviewer
label := s.getOrCreateFilterLabel(seg)
label.Bookmark = !label.Bookmark
s.Dirty = true
}
// NextBookmark navigates to the next bookmark, wrapping around if needed.
// Returns false if no bookmarks found (back at start position).
func (s *ClassifyState) NextBookmark() bool {
startFile := s.FileIdx
startSeg := s.SegmentIdx
first := true
for {
// Advance to next segment
if !s.NextSegment() {
// Wrap to start of folder
s.FileIdx = 0
s.SegmentIdx = 0
}
// Check if we've looped back to start
if !first && s.FileIdx == startFile && s.SegmentIdx == startSeg {
return false // full circle, no bookmark found
}
first = false
// Check if current segment has bookmark
if s.hasFilterBookmark() {
return true
}
}
}
// PrevBookmark navigates to the previous bookmark, wrapping around if needed.
// Returns false if no bookmarks found (back at start position).
func (s *ClassifyState) PrevBookmark() bool {
startFile := s.FileIdx
startSeg := s.SegmentIdx
first := true
for {
// Move to previous segment
if !s.PrevSegment() {
// Wrap to end of folder
s.FileIdx = len(s.DataFiles) - 1
segs := s.filteredSegs[s.FileIdx]
s.SegmentIdx = max(len(segs)-1, 0)
}
// Check if we've looped back to start
if !first && s.FileIdx == startFile && s.SegmentIdx == startSeg {
return false // full circle, no bookmark found
}
first = false
// Check if current segment has bookmark
if s.hasFilterBookmark() {
return true
}
}
}
// hasFilterBookmark checks if current segment has bookmark on filter-matching label.
func (s *ClassifyState) hasFilterBookmark() bool {
seg := s.CurrentSegment()
if seg == nil {
return false
}
label := s.getFilterLabel(seg)
return label != nil && label.Bookmark
}