mirror of
https://github.com/Ranchero-Software/NetNewsWire.git
synced 2024-12-20 14:33:04 +01:00
Continue experimentation with detail view avatars.
This commit is contained in:
parent
708e46ed18
commit
4be6df2c56
@ -133,6 +133,11 @@ class ArticleRenderer {
|
||||
|
||||
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>"
|
||||
}
|
||||
|
||||
@ -161,22 +166,29 @@ class ArticleRenderer {
|
||||
d["article_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 += " "
|
||||
}
|
||||
ix += 1
|
||||
}
|
||||
if !avatarHTML.isEmpty {
|
||||
d["avatars"] = avatarHTML
|
||||
}
|
||||
}
|
||||
|
||||
var feedLink = ""
|
||||
if let feedTitle = article.feed?.nameForDisplay {
|
||||
feedLink = feedTitle
|
||||
if let feedURL = article.feed?.homePageURL {
|
||||
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_withfavicon"] = feedLink
|
||||
@ -191,27 +203,107 @@ class ArticleRenderer {
|
||||
d["date_short"] = shortDate
|
||||
|
||||
d["byline"] = byline()
|
||||
d["author_avatar"] = authorAvatar()
|
||||
// d["author_avatar"] = authorAvatar()
|
||||
|
||||
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 {
|
||||
return ""
|
||||
}
|
||||
guard let avatarURL = author.avatarURL else {
|
||||
return ""
|
||||
}
|
||||
func html(dimension: Int) -> String {
|
||||
|
||||
var imageTag = "<img src=\"\(avatarURL)\" height=64 width=64 />"
|
||||
if let authorURL = author.url {
|
||||
imageTag = linkWithText(imageTag, authorURL)
|
||||
let imageTag = "<img src=\"\(imageURL)\" width=\"\(dimension)\" height=\"\(dimension)\""
|
||||
if let url = url {
|
||||
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 {
|
||||
|
||||
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 {
|
||||
|
@ -28,6 +28,16 @@ a:hover {
|
||||
#articleDateline a:link, #articleDateline a:visited {
|
||||
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 {
|
||||
line-height: 1.5em;
|
||||
}
|
||||
@ -38,6 +48,30 @@ a:hover {
|
||||
#authorAvatar img {
|
||||
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 {
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
@ -1,5 +1,14 @@
|
||||
<div id="articleDateline">[[feedlink_withfavicon]] [[byline]]<br />
|
||||
<span class="articleDate">[[date_medium]]</span></div>
|
||||
<div id="articleTitle"><h1>[[newsitem_title]]</h1></div>
|
||||
<div class="headerContainer"><p>[[avatars]]</p>
|
||||
<p>[[feedlink]] • [[byline]] • [[date_short]]</p></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>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user