Fix various padding issues related to longform posts
1. Make a proper threaded EventShell variant 2. Fix padding everywhere Changelog-Fixed: Fix padding on longform events
This commit is contained in:
@@ -142,7 +142,10 @@ struct EventView_Previews: PreviewProvider {
|
||||
EventView(damus: test_damus_state(), event: NostrEvent(content: "hello there https://jb55.com/s/Oct12-150217.png https://jb55.com/red-me.jb55 cool", pubkey: "pk"), show_friend_icon: true, size: .big)
|
||||
|
||||
*/
|
||||
|
||||
EventView( damus: test_damus_state(), event: test_event )
|
||||
|
||||
EventView( damus: test_damus_state(), event: test_longform_event.event, options: [.wide] )
|
||||
}
|
||||
.padding()
|
||||
}
|
||||
@@ -154,3 +157,4 @@ let test_event =
|
||||
pubkey: "pk",
|
||||
createdAt: Int64(Date().timeIntervalSince1970 - 100)
|
||||
)
|
||||
|
||||
|
||||
@@ -25,20 +25,64 @@ struct EventShell<Content: View>: View {
|
||||
}
|
||||
|
||||
func get_mention() -> Mention? {
|
||||
if self.options.contains(.nested) {
|
||||
if self.options.contains(.nested) || self.options.contains(.no_mentions) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return first_eref_mention(ev: event, privkey: state.keypair.privkey)
|
||||
}
|
||||
|
||||
func Mention(_ mention: Mention) -> some View {
|
||||
return BuilderEventView(damus: state, event_id: mention.ref.id)
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
var ActionBar: some View {
|
||||
return EventActionBar(damus_state: state, event: event)
|
||||
.padding([.top], 4)
|
||||
}
|
||||
|
||||
func Pfp(is_anon: Bool) -> some View {
|
||||
return MaybeAnonPfpView(state: state, is_anon: is_anon, pubkey: event.pubkey, size: options.contains(.small_pfp) ? eventview_pfp_size(.small) : PFP_SIZE )
|
||||
}
|
||||
|
||||
var Threaded: some View {
|
||||
HStack(alignment: .top) {
|
||||
|
||||
let is_anon = event_is_anonymous(ev: event)
|
||||
VStack {
|
||||
Pfp(is_anon: is_anon)
|
||||
|
||||
Spacer()
|
||||
}
|
||||
|
||||
VStack(alignment: .leading) {
|
||||
EventTop(state: state, event: event, is_anon: is_anon)
|
||||
|
||||
if !options.contains(.no_replying_to) {
|
||||
ReplyPart(event: event, privkey: state.keypair.privkey, profiles: state.profiles)
|
||||
}
|
||||
|
||||
content
|
||||
|
||||
if let mention = get_mention() {
|
||||
Mention(mention)
|
||||
}
|
||||
|
||||
if has_action_bar {
|
||||
ActionBar
|
||||
}
|
||||
}
|
||||
.padding([.leading], 2)
|
||||
}
|
||||
}
|
||||
|
||||
var Wide: some View {
|
||||
VStack(alignment: .leading) {
|
||||
let is_anon = event_is_anonymous(ev: event)
|
||||
|
||||
HStack(spacing: 10) {
|
||||
MaybeAnonPfpView(state: state, is_anon: is_anon, pubkey: event.pubkey, size: options.contains(.small_pfp) ? eventview_pfp_size(.small) : PFP_SIZE )
|
||||
|
||||
Pfp(is_anon: is_anon)
|
||||
|
||||
VStack {
|
||||
EventTop(state: state, event: event, is_anon: is_anon)
|
||||
ReplyPart(event: event, privkey: state.keypair.privkey, profiles: state.profiles)
|
||||
@@ -49,24 +93,44 @@ struct EventShell<Content: View>: View {
|
||||
content
|
||||
|
||||
if !options.contains(.no_mentions), let mention = get_mention() {
|
||||
|
||||
BuilderEventView(damus: state, event_id: mention.ref.id)
|
||||
Mention(mention)
|
||||
.padding(.horizontal)
|
||||
}
|
||||
|
||||
if has_action_bar {
|
||||
//EmptyRect
|
||||
EventActionBar(damus_state: state, event: event)
|
||||
.padding([.leading, .trailing, .top])
|
||||
ActionBar
|
||||
.padding(.horizontal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
Group {
|
||||
if options.contains(.wide) {
|
||||
Wide
|
||||
} else {
|
||||
Threaded
|
||||
}
|
||||
}
|
||||
.contentShape(Rectangle())
|
||||
.id(event.id)
|
||||
.frame(maxWidth: .infinity, minHeight: PFP_SIZE)
|
||||
.padding([.bottom], 2)
|
||||
}
|
||||
}
|
||||
|
||||
struct EventShell_Previews: PreviewProvider {
|
||||
|
||||
static var previews: some View {
|
||||
EventShell(state: test_damus_state(), event: test_event, options: [.no_action_bar]) {
|
||||
Text("Hello")
|
||||
VStack {
|
||||
EventShell(state: test_damus_state(), event: test_event, options: [.no_action_bar]) {
|
||||
Text("Hello")
|
||||
}
|
||||
|
||||
EventShell(state: test_damus_state(), event: test_event, options: [.no_action_bar, .wide]) {
|
||||
Text("Hello")
|
||||
}
|
||||
}
|
||||
.frame(height: 300)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,29 +24,42 @@ struct LongformPreview: View {
|
||||
func Words(_ words: Int) -> Text {
|
||||
Text(verbatim: words.description) + Text(verbatim: " ") + Text("Words")
|
||||
}
|
||||
|
||||
|
||||
var Main: some View {
|
||||
VStack(alignment: .leading, spacing: 10) {
|
||||
Text(event.title ?? "Untitled")
|
||||
.font(.title)
|
||||
|
||||
Text(event.summary ?? "")
|
||||
.foregroundColor(.gray)
|
||||
|
||||
if case .loaded(let arts) = artifacts.state,
|
||||
case .parts(let parts) = arts
|
||||
{
|
||||
Words(parts.words).font(.footnote)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
EventShell(state: state, event: event.event, options: options.union(.no_mentions)) {
|
||||
VStack(alignment: .leading, spacing: 10) {
|
||||
Text(event.title ?? "Untitled")
|
||||
.font(.title)
|
||||
|
||||
Text(event.summary ?? "")
|
||||
.foregroundColor(.gray)
|
||||
|
||||
if case .loaded(let arts) = artifacts.state,
|
||||
case .parts(let parts) = arts
|
||||
{
|
||||
Words(parts.words).font(.footnote)
|
||||
}
|
||||
|
||||
if options.contains(.wide) {
|
||||
Main.padding(.horizontal)
|
||||
} else {
|
||||
Main
|
||||
}
|
||||
.padding()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct LongformPreview_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
LongformPreview(state: test_damus_state(), ev: test_longform_event.event, options: [])
|
||||
VStack {
|
||||
LongformPreview(state: test_damus_state(), ev: test_longform_event.event, options: [])
|
||||
|
||||
LongformPreview(state: test_damus_state(), ev: test_longform_event.event, options: [.wide])
|
||||
}
|
||||
.frame(height: 400)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,18 +52,16 @@ struct LongformView: View {
|
||||
|
||||
var body: some View {
|
||||
EventShell(state: state, event: event.event, options: options) {
|
||||
|
||||
VStack {
|
||||
SelectableText(attributedString: AttributedString(stringLiteral: event.title ?? "Untitled"), size: .title)
|
||||
|
||||
NoteContentView(damus_state: state, event: event.event, show_images: true, size: .selected, options: options)
|
||||
}
|
||||
SelectableText(attributedString: AttributedString(stringLiteral: event.title ?? "Untitled"), size: .title)
|
||||
|
||||
NoteContentView(damus_state: state, event: event.event, show_images: true, size: .selected, options: options)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let test_longform_event = LongformEvent.parse(from:
|
||||
.init(content: "## Let me tell you why coffee is awesome\n**IT JUST IS**",
|
||||
.init(id: "longform_id",
|
||||
content: "## Let me tell you why coffee is awesome\n**IT JUST IS**",
|
||||
pubkey: "pk",
|
||||
kind: NostrKind.longform.rawValue,
|
||||
tags: [
|
||||
|
||||
@@ -47,8 +47,8 @@ struct SelectedEventView: View {
|
||||
.padding(.horizontal)
|
||||
}
|
||||
|
||||
EventBody(damus_state: damus, event: event, size: size, options: [.pad_content])
|
||||
|
||||
EventBody(damus_state: damus, event: event, size: size, options: [.wide])
|
||||
|
||||
if let mention = first_eref_mention(ev: event, privkey: damus.keypair.privkey) {
|
||||
BuilderEventView(damus: damus, event_id: mention.ref.id)
|
||||
.padding(.horizontal)
|
||||
@@ -88,6 +88,5 @@ struct SelectedEventView: View {
|
||||
struct SelectedEventView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
SelectedEventView(damus: test_damus_state(), event: test_event, size: .selected)
|
||||
.padding()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,13 +14,12 @@ struct EventViewOptions: OptionSet {
|
||||
static let no_replying_to = EventViewOptions(rawValue: 1 << 1)
|
||||
static let wide = EventViewOptions(rawValue: 1 << 3)
|
||||
static let truncate_content = EventViewOptions(rawValue: 1 << 4)
|
||||
static let pad_content = EventViewOptions(rawValue: 1 << 5)
|
||||
static let no_translate = EventViewOptions(rawValue: 1 << 6)
|
||||
static let small_pfp = EventViewOptions(rawValue: 1 << 7)
|
||||
static let nested = EventViewOptions(rawValue: 1 << 8)
|
||||
static let top_zap = EventViewOptions(rawValue: 1 << 9)
|
||||
static let no_mentions = EventViewOptions(rawValue: 1 << 10)
|
||||
|
||||
static let no_translate = EventViewOptions(rawValue: 1 << 5)
|
||||
static let small_pfp = EventViewOptions(rawValue: 1 << 6)
|
||||
static let nested = EventViewOptions(rawValue: 1 << 7)
|
||||
static let top_zap = EventViewOptions(rawValue: 1 << 8)
|
||||
static let no_mentions = EventViewOptions(rawValue: 1 << 9)
|
||||
|
||||
static let embedded: EventViewOptions = [.no_action_bar, .small_pfp, .wide, .truncate_content, .nested]
|
||||
}
|
||||
|
||||
@@ -39,51 +38,12 @@ struct TextEvent: View {
|
||||
self.evdata = damus.events.get_cache_data(event.id)
|
||||
}
|
||||
|
||||
var has_action_bar: Bool {
|
||||
!options.contains(.no_action_bar)
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
Group {
|
||||
if options.contains(.wide) {
|
||||
WideStyle
|
||||
} else {
|
||||
ThreadedStyle
|
||||
}
|
||||
}
|
||||
.contentShape(Rectangle())
|
||||
.id(event.id)
|
||||
.frame(maxWidth: .infinity, minHeight: PFP_SIZE)
|
||||
.padding([.bottom], 2)
|
||||
}
|
||||
|
||||
func Pfp(is_anon: Bool) -> some View {
|
||||
MaybeAnonPfpView(state: damus, is_anon: is_anon, pubkey: pubkey, size: options.contains(.small_pfp) ? eventview_pfp_size(.small) : PFP_SIZE )
|
||||
}
|
||||
|
||||
func TopPart(is_anon: Bool) -> some View {
|
||||
HStack(alignment: .center, spacing: 0) {
|
||||
ProfileName(is_anon: is_anon)
|
||||
TimeDot()
|
||||
RelativeTime(time: self.evdata.relative_time)
|
||||
Spacer()
|
||||
EventMenuContext(damus: damus, event: event)
|
||||
}
|
||||
.lineLimit(1)
|
||||
}
|
||||
|
||||
var WideStyle: some View {
|
||||
EventShell(state: damus, event: event, options: options) {
|
||||
EvBody(options: self.options.union(.pad_content))
|
||||
EvBody(options: options)
|
||||
}
|
||||
}
|
||||
|
||||
func ProfileName(is_anon: Bool) -> some View {
|
||||
let profile = damus.profiles.lookup(id: pubkey)
|
||||
let pk = is_anon ? ANON_PUBKEY : pubkey
|
||||
return EventProfileName(pubkey: pk, profile: profile, damus: damus, size: .normal)
|
||||
}
|
||||
|
||||
|
||||
func EvBody(options: EventViewOptions) -> some View {
|
||||
let show_imgs = should_show_images(settings: damus.settings, contacts: damus.contacts, ev: event, our_pubkey: damus.pubkey)
|
||||
return NoteContentView(
|
||||
@@ -93,61 +53,8 @@ struct TextEvent: View {
|
||||
size: .normal,
|
||||
options: options
|
||||
)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
}
|
||||
|
||||
func Mention(_ mention: Mention) -> some View {
|
||||
return BuilderEventView(damus: damus, event_id: mention.ref.id)
|
||||
}
|
||||
|
||||
var ActionBar: some View {
|
||||
return EventActionBar(damus_state: damus, event: event)
|
||||
.padding([.top], 4)
|
||||
}
|
||||
|
||||
var EmptyRect: some View {
|
||||
return Rectangle().frame(height: 2).opacity(0)
|
||||
}
|
||||
|
||||
func get_mention() -> Mention? {
|
||||
if self.options.contains(.nested) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return first_eref_mention(ev: event, privkey: damus.keypair.privkey)
|
||||
}
|
||||
|
||||
var ThreadedStyle: some View {
|
||||
HStack(alignment: .top) {
|
||||
|
||||
let is_anon = event_is_anonymous(ev: event)
|
||||
VStack {
|
||||
Pfp(is_anon: is_anon)
|
||||
|
||||
Spacer()
|
||||
}
|
||||
|
||||
VStack(alignment: .leading) {
|
||||
TopPart(is_anon: is_anon)
|
||||
|
||||
if !options.contains(.no_replying_to) {
|
||||
ReplyPart(event: event, privkey: damus.keypair.privkey, profiles: damus.profiles)
|
||||
}
|
||||
|
||||
EvBody(options: self.options)
|
||||
|
||||
if let mention = get_mention() {
|
||||
Mention(mention)
|
||||
}
|
||||
|
||||
if has_action_bar {
|
||||
EmptyRect
|
||||
ActionBar
|
||||
}
|
||||
}
|
||||
.padding([.leading], 2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func event_has_tag(ev: NostrEvent, tag: String) -> Bool {
|
||||
|
||||
@@ -54,7 +54,7 @@ struct NoteContentView: View {
|
||||
}
|
||||
|
||||
var with_padding: Bool {
|
||||
return options.contains(.pad_content)
|
||||
return options.contains(.wide)
|
||||
}
|
||||
|
||||
var preview: LinkViewRepresentable? {
|
||||
@@ -185,16 +185,23 @@ struct NoteContentView: View {
|
||||
|
||||
func artifactPartsView(_ parts: [ArtifactPart]) -> some View {
|
||||
|
||||
LazyVStack {
|
||||
LazyVStack(alignment: .leading) {
|
||||
ForEach(parts.indices, id: \.self) { ind in
|
||||
let part = parts[ind]
|
||||
switch part {
|
||||
case .text(let txt):
|
||||
txt
|
||||
.padding(.horizontal)
|
||||
if with_padding {
|
||||
txt.padding(.horizontal)
|
||||
} else {
|
||||
txt
|
||||
}
|
||||
case .invoice(let inv):
|
||||
InvoiceView(our_pubkey: damus_state.pubkey, invoice: inv, settings: damus_state.settings)
|
||||
.padding(.horizontal)
|
||||
if with_padding {
|
||||
InvoiceView(our_pubkey: damus_state.pubkey, invoice: inv, settings: damus_state.settings)
|
||||
.padding(.horizontal)
|
||||
} else {
|
||||
InvoiceView(our_pubkey: damus_state.pubkey, invoice: inv, settings: damus_state.settings)
|
||||
}
|
||||
case .media(let media):
|
||||
Text("media \(media.url.absoluteString)")
|
||||
}
|
||||
@@ -211,6 +218,7 @@ struct NoteContentView: View {
|
||||
MainContent(artifacts: separated)
|
||||
}
|
||||
}
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
@@ -277,15 +285,6 @@ func mention_str(_ m: Mention, profiles: Profiles) -> CompatibleText {
|
||||
}
|
||||
}
|
||||
|
||||
struct NoteContentView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
let state = test_damus_state()
|
||||
let content = "hi there ¯\\_(ツ)_/¯ https://jb55.com/s/Oct12-150217.png 5739a762ef6124dd.jpg"
|
||||
NoteContentView(damus_state: state, event: NostrEvent(content: content, pubkey: "pk"), show_images: true, size: .normal, options: [])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
enum NoteArtifacts {
|
||||
case separated(NoteArtifactsSeparated)
|
||||
case parts(NoteArtifactsParts)
|
||||
@@ -652,3 +651,18 @@ func trim_suffix(_ str: String) -> String {
|
||||
func trim_prefix(_ str: String) -> String {
|
||||
return str.replacingOccurrences(of: "^\\s+", with: "", options: .regularExpression)
|
||||
}
|
||||
|
||||
struct NoteContentView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
let state = test_damus_state()
|
||||
|
||||
VStack {
|
||||
NoteContentView(damus_state: state, event: test_event, show_images: true, size: .normal, options: [])
|
||||
|
||||
NoteContentView(damus_state: state, event: test_longform_event.event, show_images: true, size: .normal, options: [.wide])
|
||||
.border(Color.red)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -51,30 +51,41 @@ struct ReplyView: View {
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func line(height: CGFloat) -> some View {
|
||||
return Rectangle()
|
||||
.fill(Color.gray.opacity(0.25))
|
||||
.frame(width: 2, height: height)
|
||||
.offset(x: 25, y: 40)
|
||||
.padding(.leading)
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading) {
|
||||
|
||||
EventView(damus: damus, event: replying_to, options: [.no_action_bar])
|
||||
.padding()
|
||||
.background(GeometryReader { geometry in
|
||||
let eventHeight = geometry.frame(in: .global).height
|
||||
Rectangle()
|
||||
.fill(Color.gray.opacity(0.25))
|
||||
.frame(width: 2, height: eventHeight + 7)
|
||||
.offset(x: 25, y: 40)
|
||||
.padding(.leading)
|
||||
line(height: eventHeight)
|
||||
})
|
||||
|
||||
ReplyingToSection
|
||||
.background(GeometryReader { geometry in
|
||||
let replyingToHeight = geometry.frame(in: .global).height
|
||||
Rectangle()
|
||||
.fill(Color.gray.opacity(0.25))
|
||||
.frame(width: 2, height: replyingToHeight)
|
||||
.offset(x: 25, y: 40)
|
||||
.padding(.leading)
|
||||
line(height: replyingToHeight)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ReplyView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
VStack {
|
||||
ReplyView(replying_to: test_event, damus: test_damus_state(), originalReferences: .constant([]), references: .constant([]))
|
||||
.frame(height: 300)
|
||||
|
||||
ReplyView(replying_to: test_longform_event.event, damus: test_damus_state(), originalReferences: .constant([]), references: .constant([]))
|
||||
.frame(height: 300)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ struct RepostedEvent: View {
|
||||
.buttonStyle(PlainButtonStyle())
|
||||
|
||||
//SelectedEventView(damus: damus, event: inner_ev, size: .normal)
|
||||
EventView(damus: damus, event: inner_ev, pubkey: inner_ev.pubkey, options: options)
|
||||
EventView(damus: damus, event: inner_ev, pubkey: inner_ev.pubkey, options: options.union(.wide))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user