Continue experimentation with detail view avatars.

This commit is contained in:
Brent Simmons 2017-12-29 17:10:50 -08:00
parent 708e46ed18
commit 4be6df2c56
3 changed files with 161 additions and 26 deletions

View File

@ -133,6 +133,11 @@ class ArticleRenderer {
private func linkWithText(_ text: String, _ href: String) -> String { private func linkWithText(_ text: String, _ href: String) -> String {
return ArticleRenderer.linkWithText(text, href)
}
private static func linkWithText(_ text: String, _ href: String) -> String {
return "<a href=\"\(href)\">\(text)</a>" return "<a href=\"\(href)\">\(text)</a>"
} }
@ -161,22 +166,29 @@ class ArticleRenderer {
d["article_description"] = body d["article_description"] = body
d["newsitem_description"] = body d["newsitem_description"] = body
d["avatars"] = ""
if let avatars = avatarsToShow() {
var avatarHTML = ""
var ix = 0
let ct = avatars.count
for avatar in avatars {
avatarHTML += avatar.html(dimension: 64)
if ix < ct - 1 {
avatarHTML += "&nbsp;"
}
ix += 1
}
if !avatarHTML.isEmpty {
d["avatars"] = avatarHTML
}
}
var feedLink = "" var feedLink = ""
if let feedTitle = article.feed?.nameForDisplay { if let feedTitle = article.feed?.nameForDisplay {
feedLink = feedTitle feedLink = feedTitle
if let feedURL = article.feed?.homePageURL { if let feedURL = article.feed?.homePageURL {
feedLink = linkWithTextAndClass(feedTitle, feedURL, "feedLink") feedLink = linkWithTextAndClass(feedTitle, feedURL, "feedLink")
} }
if let feedIcon = article.feed?.iconURL {
let feedIconImage = "<img src=\"\(feedIcon)\" height=\"48\" width=\"48\" class=\"feedIcon\" />"
if let feedURL = article.feed?.homePageURL {
let feedIconImageLink = linkWithText(feedIconImage, feedURL)
feedLink = feedIconImageLink + " " + feedLink
}
else {
feedLink = feedIconImage + " " + feedLink
}
}
} }
d["feedlink"] = feedLink d["feedlink"] = feedLink
d["feedlink_withfavicon"] = feedLink d["feedlink_withfavicon"] = feedLink
@ -191,27 +203,107 @@ class ArticleRenderer {
d["date_short"] = shortDate d["date_short"] = shortDate
d["byline"] = byline() d["byline"] = byline()
d["author_avatar"] = authorAvatar() // d["author_avatar"] = authorAvatar()
return d return d
} }
private func authorAvatar() -> String { struct Avatar {
let imageURL: String
let url: String?
guard let authors = article.authors, authors.count == 1, let author = authors.first else { func html(dimension: Int) -> String {
return ""
}
guard let avatarURL = author.avatarURL else {
return ""
}
var imageTag = "<img src=\"\(avatarURL)\" height=64 width=64 />" let imageTag = "<img src=\"\(imageURL)\" width=\"\(dimension)\" height=\"\(dimension)\""
if let authorURL = author.url { if let url = url {
imageTag = linkWithText(imageTag, authorURL) return linkWithText(imageTag, url)
}
return imageTag
} }
return "<div id=authorAvatar>\(imageTag)</div>"
} }
private func singleArticleSpecifiedAuthor() -> Author? {
// The author of this article, if just one.
if let authors = article.authors, authors.count == 1 {
return authors.first!
}
return nil
}
private func singleFeedSpecifiedAuthor() -> Author? {
if let authors = article.feed?.authors, authors.count == 1 {
return authors.first!
}
return nil
}
private func feedAvatar() -> Avatar? {
guard let feedIconURL = article.feed?.iconURL else {
return nil
}
return Avatar(imageURL: feedIconURL, url: article.feed?.homePageURL ?? article.feed?.url)
}
private func authorAvatar() -> Avatar? {
if let author = singleArticleSpecifiedAuthor(), let imageURL = author.avatarURL {
return Avatar(imageURL: imageURL, url: author.url)
}
if let author = singleFeedSpecifiedAuthor(), let imageURL = author.avatarURL {
return Avatar(imageURL: imageURL, url: author.url)
}
return nil
}
private func avatarsToShow() -> [Avatar]? {
var avatars = [Avatar]()
if let avatar = feedAvatar() {
avatars.append(avatar)
}
if let avatar = authorAvatar() {
avatars.append(avatar)
}
return avatars.isEmpty ? nil : avatars
}
private func avatarToUse() -> Avatar? {
// Use author if article specifies an author, otherwise use feed icon.
// If no feed icon, use feed-specified author.
if let author = singleArticleSpecifiedAuthor(), let imageURL = author.avatarURL {
return Avatar(imageURL: imageURL, url: author.url)
}
if let feedIconURL = article.feed?.iconURL {
return Avatar(imageURL: feedIconURL, url: article.feed?.homePageURL ?? article.feed?.url)
}
if let author = singleFeedSpecifiedAuthor(), let imageURL = author.avatarURL {
return Avatar(imageURL: imageURL, url: author.url)
}
return nil
}
// private func authorAvatar() -> String {
//
// guard let authors = article.authors, authors.count == 1, let author = authors.first else {
// return ""
// }
// guard let avatarURL = author.avatarURL else {
// return ""
// }
//
// var imageTag = "<img src=\"\(avatarURL)\" height=64 width=64 />"
// if let authorURL = author.url {
// imageTag = linkWithText(imageTag, authorURL)
// }
// return "<div id=authorAvatar>\(imageTag)</div>"
// }
private func byline() -> String { private func byline() -> String {
guard let authors = article.authors ?? article.feed?.authors, !authors.isEmpty else { guard let authors = article.authors ?? article.feed?.authors, !authors.isEmpty else {
@ -249,7 +341,7 @@ class ArticleRenderer {
} }
return "" + byline return byline
} }
private func renderedHTML() -> String { private func renderedHTML() -> String {

View File

@ -28,6 +28,16 @@ a:hover {
#articleDateline a:link, #articleDateline a:visited { #articleDateline a:link, #articleDateline a:visited {
color: rgba(0, 0, 0, 0.4); color: rgba(0, 0, 0, 0.4);
} }
#articleDateline img {
border-radius: 7px;
}
.articleDate {
color: #2db6ff;
text-align: right;
border-bottom: 1px solid rgba(0, 0, 0, 0.5);
padding-bottom: 8px;
margin-bottom: 1em;
}
#articleDescription { #articleDescription {
line-height: 1.5em; line-height: 1.5em;
} }
@ -38,6 +48,30 @@ a:hover {
#authorAvatar img { #authorAvatar img {
border-radius: 5px; border-radius: 5px;
} }
.rightAlign {
text-align: right;
}
.leftAlign {
text-align: left;
}
.headerContainer {
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
color: rgba(0, 0, 0, 0.3);
}
.header {
color: rgba(0, 0, 0, 0.3);
}
.headerTable {
width: 100%;
}
.headerContainer img {
border-radius: 7px;
margin-right: 8px;
}
.headerContainer a:link, .headerContainer a:visited {
color: rgba(0, 0, 0, 0.5);
}
.feedIcon { .feedIcon {
border-radius: 5px; border-radius: 5px;
} }

View File

@ -1,5 +1,14 @@
<div id="articleDateline">[[feedlink_withfavicon]] [[byline]]<br /> <div class="headerContainer"><p>[[avatars]]</p>
<span class="articleDate">[[date_medium]]</span></div> <p>[[feedlink]] • [[byline]] • [[date_short]]</p></div>
<div id="articleTitle"><h1>[[newsitem_title]]</h1></div> <!--<div class="headerContainer">
<table class="headerTable">
<tr>
<td class="header leftAlign">[[avatars]]</td>
<td class="header leftAlign">[[date_medium]]<br />[[feedlink]]<br />[[byline]]</td>
</tr>
</table>
</div>-->
<div class="articleTitle"><h1>[[newsitem_title]]</h1></div>
<div id="articleDescription">[[newsitem_description]]</div> <div id="articleDescription">[[newsitem_description]]</div>