Coffee journaling on ATProto (alpha) alpha.arabica.social
coffee
17
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: add filter type to pourover details

+49 -5
+6
internal/atproto/records.go
··· 226 226 if brew.PouroverParams.BypassWater > 0 { 227 227 pp["bypassWater"] = brew.PouroverParams.BypassWater 228 228 } 229 + if brew.PouroverParams.Filter != "" { 230 + pp["filter"] = brew.PouroverParams.Filter 231 + } 229 232 if len(pp) > 0 { 230 233 record["pouroverParams"] = pp 231 234 } ··· 343 346 } 344 347 if v, ok := toFloat64(ppRaw["bypassWater"]); ok { 345 348 pp.BypassWater = int(v) 349 + } 350 + if v, ok := ppRaw["filter"].(string); ok { 351 + pp.Filter = v 346 352 } 347 353 brew.PouroverParams = pp 348 354 }
+3
internal/atproto/records_test.go
··· 761 761 BloomSeconds: 45, 762 762 DrawdownSeconds: 30, 763 763 BypassWater: 100, 764 + Filter: "paper", 764 765 }, 765 766 } 766 767 ··· 773 774 assert.Equal(t, 45, pp["bloomSeconds"]) 774 775 assert.Equal(t, 30, pp["drawdownSeconds"]) 775 776 assert.Equal(t, 100, pp["bypassWater"]) 777 + assert.Equal(t, "paper", pp["filter"]) 776 778 777 779 restored, err := RecordToBrew(record, "at://did:plc:test/social.arabica.alpha.brew/tid123") 778 780 assert.NoError(t, err) ··· 781 783 assert.Equal(t, 45, restored.PouroverParams.BloomSeconds) 782 784 assert.Equal(t, 30, restored.PouroverParams.DrawdownSeconds) 783 785 assert.Equal(t, 100, restored.PouroverParams.BypassWater) 786 + assert.Equal(t, "paper", restored.PouroverParams.Filter) 784 787 }
+3 -1
internal/handlers/brew.go
··· 515 515 bloomSecsStr := r.FormValue("pourover_bloom_seconds") 516 516 drawdownStr := r.FormValue("pourover_drawdown_seconds") 517 517 bypassStr := r.FormValue("pourover_bypass_water") 518 + filterStr := strings.TrimSpace(r.FormValue("pourover_filter")) 518 519 519 - if bloomWaterStr == "" && bloomSecsStr == "" && drawdownStr == "" && bypassStr == "" { 520 + if bloomWaterStr == "" && bloomSecsStr == "" && drawdownStr == "" && bypassStr == "" && filterStr == "" { 520 521 return nil 521 522 } 522 523 ··· 533 534 if v, err := strconv.Atoi(bypassStr); err == nil && v > 0 { 534 535 pp.BypassWater = v 535 536 } 537 + pp.Filter = filterStr 536 538 return pp 537 539 } 538 540
+5 -4
internal/models/models.go
··· 194 194 195 195 // PouroverParams holds pour-over-specific brewing parameters 196 196 type PouroverParams struct { 197 - BloomWater int `json:"bloom_water"` // Bloom water in grams 198 - BloomSeconds int `json:"bloom_seconds"` // Bloom wait time in seconds 199 - DrawdownSeconds int `json:"drawdown_seconds"` // Drawdown time in seconds 200 - BypassWater int `json:"bypass_water"` // Bypass water in grams 197 + BloomWater int `json:"bloom_water"` // Bloom water in grams 198 + BloomSeconds int `json:"bloom_seconds"` // Bloom wait time in seconds 199 + DrawdownSeconds int `json:"drawdown_seconds"` // Drawdown time in seconds 200 + BypassWater int `json:"bypass_water"` // Bypass water in grams 201 + Filter string `json:"filter"` // Filter type (e.g. "paper", "metal", "cloth") 201 202 } 202 203 203 204 type Recipe struct {
+5
internal/web/components/record_brew.templ
··· 102 102 <span class="text-label">Bypass:</span> { fmt.Sprintf("%dg", brew.PouroverParams.BypassWater) } 103 103 </div> 104 104 } 105 + if brew.PouroverParams.Filter != "" { 106 + <div> 107 + <span class="text-label">Filter:</span> { brew.PouroverParams.Filter } 108 + </div> 109 + } 105 110 } 106 111 </div> 107 112 <!-- Pours as inline pills -->
+19
internal/web/pages/brew_form.templ
··· 809 809 Class: "w-full form-input-lg", 810 810 }), 811 811 ) 812 + @components.FormField( 813 + components.FormFieldProps{ 814 + Label: "Filter", 815 + HelperText: "Type of filter used", 816 + }, 817 + components.TextInput(components.TextInputProps{ 818 + Name: "pourover_filter", 819 + Value: getPouroverFilter(props), 820 + Placeholder: "e.g. paper, metal, cloth", 821 + Class: "w-full form-input-lg", 822 + }), 823 + ) 812 824 </fieldset> 813 825 </div> 814 826 } ··· 861 873 } 862 874 return "" 863 875 } 876 + 877 + func getPouroverFilter(props BrewFormProps) string { 878 + if props.Brew != nil && props.Brew.PouroverParams != nil { 879 + return props.Brew.PouroverParams.Filter 880 + } 881 + return "" 882 + }
+3
internal/web/pages/brew_view.templ
··· 196 196 if brew.PouroverParams.BypassWater > 0 { 197 197 @components.DetailField(components.DetailFieldProps{Icon: components.IconDroplet(), Label: "Bypass Water", Value: fmt.Sprintf("%dg", brew.PouroverParams.BypassWater)}) 198 198 } 199 + if brew.PouroverParams.Filter != "" { 200 + @components.DetailField(components.DetailFieldProps{Icon: components.IconSliders(), Label: "Filter", Value: brew.PouroverParams.Filter}) 201 + } 199 202 } 200 203 </div> 201 204 }
+5
lexicons/social.arabica.alpha.brew.json
··· 159 159 "type": "integer", 160 160 "minimum": 0, 161 161 "description": "Bypass water added after brewing in grams" 162 + }, 163 + "filter": { 164 + "type": "string", 165 + "maxLength": 100, 166 + "description": "Type of filter used (e.g. paper, metal, cloth)" 162 167 } 163 168 } 164 169 }