mirror of
https://github.com/iv-org/invidious.git
synced 2026-09-06 17:12:45 -05:00
fix(comments): render nested attachment runs
Render attachment runs contained by command runs while consuming the source cursor in one pass. Cover equal-offset and nested zero-length attachments so link processing no longer drops images.
This commit is contained in:
parent
a570e0b43e
commit
ff8aa06f84
@ -96,4 +96,55 @@ Spectator.describe "parse_description" do
|
|||||||
|
|
||||||
expect(parse_description(description, "video-id")).to eq("one:custom-emoji:two")
|
expect(parse_description(description, "video-id")).to eq("one:custom-emoji:two")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "renders attachments nested in command runs" do
|
||||||
|
description = JSON.parse(<<-JSON)
|
||||||
|
{
|
||||||
|
"content": "abcd",
|
||||||
|
"commandRuns": [{
|
||||||
|
"startIndex": 0,
|
||||||
|
"length": 4,
|
||||||
|
"onTap": {"innertubeCommand": {"watchEndpoint": {"videoId": "linked-video"}}}
|
||||||
|
}],
|
||||||
|
"attachmentRuns": [
|
||||||
|
{
|
||||||
|
"startIndex": 0,
|
||||||
|
"length": 0,
|
||||||
|
"element": {
|
||||||
|
"type": {
|
||||||
|
"imageType": {
|
||||||
|
"image": {
|
||||||
|
"sources": [{"url": "https://lh3.googleusercontent.com/emoji-start=s16", "width": 16, "height": 16}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {"accessibilityProperties": {"label": "emoji-at-start"}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"startIndex": 2,
|
||||||
|
"length": 0,
|
||||||
|
"element": {
|
||||||
|
"type": {
|
||||||
|
"imageType": {
|
||||||
|
"image": {
|
||||||
|
"sources": [{"url": "https://lh3.googleusercontent.com/emoji-inside=s16", "width": 16, "height": 16}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {"accessibilityProperties": {"label": "emoji-inside"}}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
JSON
|
||||||
|
|
||||||
|
expect(parse_description(description, "video-id")).to eq(
|
||||||
|
%(<a href="/watch?v=linked-video">) +
|
||||||
|
%(<img alt="emoji-at-start" src="/ggpht/emoji-start=s16" title="emoji-at-start" width="16" height="16" class="channel-emoji" />) +
|
||||||
|
"ab" +
|
||||||
|
%(<img alt="emoji-inside" src="/ggpht/emoji-inside=s16" title="emoji-inside" width="16" height="16" class="channel-emoji" />) +
|
||||||
|
"cd</a>"
|
||||||
|
)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -93,6 +93,44 @@ private def parse_attachment_run(attachment) : String?
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private def attachment_run_inside_command?(attachment, command) : Bool
|
||||||
|
attachment_start = attachment["startIndex"].as_i
|
||||||
|
attachment_end = attachment_start + attachment["length"].as_i
|
||||||
|
command_start = command["startIndex"].as_i
|
||||||
|
command_end = command_start + command["length"].as_i
|
||||||
|
|
||||||
|
attachment_start >= command_start && attachment_end <= command_end
|
||||||
|
end
|
||||||
|
|
||||||
|
private def parse_command_run(command, nested_attachments, iter, video_id : String) : String
|
||||||
|
command_start = command["startIndex"].as_i
|
||||||
|
command_length = command["length"].as_i
|
||||||
|
|
||||||
|
command_content = String.build do |command_str|
|
||||||
|
index = 0
|
||||||
|
nested_attachments.sort_by { |attachment| attachment["startIndex"].as_i }.each do |attachment|
|
||||||
|
relative_start = attachment["startIndex"].as_i - command_start
|
||||||
|
next if relative_start < index
|
||||||
|
|
||||||
|
index += copy_string(command_str, iter, relative_start - index)
|
||||||
|
if attachment_html = parse_attachment_run(attachment)
|
||||||
|
command_str << attachment_html
|
||||||
|
index += skip_string(iter, attachment["length"].as_i)
|
||||||
|
else
|
||||||
|
index += copy_string(command_str, iter, attachment["length"].as_i)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
copy_string(command_str, iter, command_length - index) if index < command_length
|
||||||
|
end
|
||||||
|
|
||||||
|
link = command_content
|
||||||
|
if on_tap = command.dig?("onTap", "innertubeCommand")
|
||||||
|
link = parse_link_endpoint(on_tap, command_content, video_id)
|
||||||
|
end
|
||||||
|
link
|
||||||
|
end
|
||||||
|
|
||||||
private def parse_description_with_attachments(content : String, commands, attachments, video_id : String) : String
|
private def parse_description_with_attachments(content : String, commands, attachments, video_id : String) : String
|
||||||
runs = [] of Tuple(Int32, Int32, String, JSON::Any)
|
runs = [] of Tuple(Int32, Int32, String, JSON::Any)
|
||||||
|
|
||||||
@ -101,6 +139,8 @@ private def parse_description_with_attachments(content : String, commands, attac
|
|||||||
end
|
end
|
||||||
|
|
||||||
attachments.each do |attachment|
|
attachments.each do |attachment|
|
||||||
|
next if commands.try &.any? { |command| attachment_run_inside_command?(attachment, command) }
|
||||||
|
|
||||||
runs << {attachment["startIndex"].as_i, attachment["length"].as_i, "attachment", attachment}
|
runs << {attachment["startIndex"].as_i, attachment["length"].as_i, "attachment", attachment}
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -122,15 +162,10 @@ private def parse_description_with_attachments(content : String, commands, attac
|
|||||||
case run[2]
|
case run[2]
|
||||||
when "command"
|
when "command"
|
||||||
command = run[3]
|
command = run[3]
|
||||||
command_content = String.build(length) do |command_str|
|
nested_attachments = attachments.select do |attachment|
|
||||||
copy_string(command_str, iter, length)
|
attachment_run_inside_command?(attachment, command)
|
||||||
end
|
end
|
||||||
|
str << parse_command_run(command, nested_attachments, iter, video_id)
|
||||||
link = command_content
|
|
||||||
if on_tap = command.dig?("onTap", "innertubeCommand")
|
|
||||||
link = parse_link_endpoint(on_tap, command_content, video_id)
|
|
||||||
end
|
|
||||||
str << link
|
|
||||||
when "attachment"
|
when "attachment"
|
||||||
attachment = run[3]
|
attachment = run[3]
|
||||||
if attachment_html = parse_attachment_run(attachment)
|
if attachment_html = parse_attachment_run(attachment)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user