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 {
|
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 += " "
|
||||||
|
}
|
||||||
|
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 {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user