Skip to content

Commit

Permalink
Header page with small icons (#114)
Browse files Browse the repository at this point in the history
* Header page with small icons

* Adjust title position based on content size
  • Loading branch information
stephanebisson authored Jan 31, 2020
1 parent f67e36e commit 8580e42
Show file tree
Hide file tree
Showing 12 changed files with 149 additions and 99 deletions.
3 changes: 2 additions & 1 deletion i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
},
"article-action-sections": "Sections",
"article-action-quickfacts": "Quick Facts",
"article-action-gallery": "Gallery",
"article-action-languages": "Language",
"article-language-available": "Available in $1 {{PLURAL:$1|language|languages}}",
"article-language-loading-message": "Loading languages...",
"article-loading-message": "Loading page...",
Expand All @@ -26,7 +28,6 @@
"header-settings": "Settings",
"header-textsize": "Article text size",
"menu-previous": "Previous article",
"menu-language": "Language",
"menu-textsize": "Text size",
"no-result-found": "No results found",
"softkey-about": "About",
Expand Down
3 changes: 2 additions & 1 deletion i18n/qqq.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
},
"article-action-sections": "The action button sections text on the first page of the article used to open the section page and the label of the Section item shown in the Menu page.",
"article-action-quickfacts": "The action button quick facts text on the first page of the article used to open the quick facts page and the label of the Quick facts item shown in the Menu page.",
"article-action-gallery": "The action button gallery text on the first page of the article used to open the gallery page.",
"article-action-languages": "The action button language text on the first page of the article used to open the language page and the label of the language item shown in the Menu page.",
"article-language-available": "The header title of the article language search page. The word \"available\" refers to the article.",
"article-language-loading-message": "The message when loading the article's language page. Shown in the article language page",
"article-loading-message": "The message when loading the article. Shown in the article page",
Expand All @@ -25,7 +27,6 @@
"header-settings": "The header title of the settings page",
"header-textsize": "The header title of the text size page",
"menu-previous": "Label of the Previous article item. Shown in the Menu page.",
"menu-language": "Label of the Language item. Shown in the Menu page.",
"menu-textsize": "Label of the Text size item list. Shown in the Menu menu.",
"no-result-found": "No result found text. Shown in the search and language list view",
"softkey-about": "Label of the about softkey. Shown in image gallery page.",
Expand Down
6 changes: 6 additions & 0 deletions images/icon-audio.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions images/icon-gallery.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions images/icon-languages.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions images/icon-quickfacts.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions images/icon-sections.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 0 additions & 6 deletions images/quickfacts.svg

This file was deleted.

6 changes: 0 additions & 6 deletions images/sections.svg

This file was deleted.

110 changes: 63 additions & 47 deletions src/components/Article.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { h, Fragment } from 'preact'
import { memo } from 'preact/compat'
import { useState, useRef, useEffect } from 'preact/hooks'
import { useState, useRef, useEffect, useLayoutEffect } from 'preact/hooks'
import {
ReferencePreview, ArticleToc, ArticleLanguage,
ArticleMenu, ArticleFooter, Loading, QuickFacts,
Expand All @@ -22,11 +22,24 @@ const ArticleBody = memo(({ content }) => {
)
})

const ArticleActions = ({ actions }) => {
const i18n = useI18n()
return (
<div class='article-actions'>
{ actions.filter(a => a.enabled).map(action => (
<div class='article-actions-button' data-action={action.name} key={action.name}>
<img src={`images/icon-${action.name}.svg`} />
<label>{i18n.i18n(`article-action-${action.name}`)}</label>
</div>
)) }
</div>
)
}

const ArticleSection = ({
lang, imageUrl, title, description, hasActions, isFooter,
content, page, showToc, goToSubpage, references,
hasInfobox, articleTitle, suggestedArticles, showQuickFacts,
showGallery, hasGallery
lang, imageUrl, title, description, actions, isFooter,
content, page, goToSubpage, references,
articleTitle, suggestedArticles
}) => {
const contentRef = useRef()
const i18n = useI18n()
Expand All @@ -35,12 +48,9 @@ const ArticleSection = ({

const linkHandlers = {
action: ({ action }) => {
if (action === 'quickfacts') {
showQuickFacts()
} else if (action === 'sections') {
showToc()
} else if (action === 'gallery') {
showGallery()
const targetAction = actions.find(a => a.name === action)
if (targetAction) {
targetAction.handler()
}
},
reference: ({ referenceId }) => {
Expand All @@ -54,37 +64,41 @@ const ArticleSection = ({

useArticleLinksNavigation('Article', lang, contentRef, linkHandlers, [page, textSize])

useLayoutEffect(() => {
if (!contentRef.current) {
return
}
const MAX_TITLE_HEIGHT = 140
const titleNode = contentRef.current.querySelector('.title')
if (titleNode.getBoundingClientRect().height > MAX_TITLE_HEIGHT) {
titleNode.classList.add('clamp')
}
if (imageUrl) {
const introNode = contentRef.current.querySelector('.intro')
let introHeight = introNode.getBoundingClientRect().height
introHeight += 34 // Magic number needed to make it work
const articleSectionHeight = contentRef.current.getBoundingClientRect().height
const marginTop = articleSectionHeight - introHeight
const cardNode = contentRef.current.querySelector('.card')
cardNode.style.marginTop = `${marginTop}px`
}
}, [title, imageUrl, textSize])

return (
<div class='article-section' ref={contentRef}>
{ imageUrl && <div class='lead-image' style={{ backgroundImage: `url(${imageUrl})` }} /> }
<div class={'card' + (imageUrl ? ' with-image' : '')}>
<div class='title adjustable-font-size' dangerouslySetInnerHTML={{ __html: title }} />
{ description && (
<Fragment>
<div class='desc adjustable-font-size'>{description}</div>
<div class='line' />
</Fragment>
) }
{ hasActions && (
<div class='article-actions'>
<div class='article-actions-button' data-action='sections'>
<img src='images/sections.svg' /><br />
<label>{i18n.i18n('article-action-sections')}</label>
</div>
{ hasInfobox && (
<div class='article-actions-button' data-action='quickfacts'>
<img src='images/quickfacts.svg' /><br />
<label>{i18n.i18n('article-action-quickfacts')}</label>
</div>
) }
{ hasGallery && (
<div class='article-actions-button' data-action='gallery'>
<img src='images/sections.svg' /><br />
<label>Gallery</label>
</div>
) }
</div>
) }
<div
class='article-section'
ref={contentRef}
style={imageUrl ? { backgroundImage: `url(${imageUrl})` } : {}}>
<div class='card'>
<div class='intro'>
<div class='title adjustable-font-size' dangerouslySetInnerHTML={{ __html: title }} />
{ description && (
<Fragment>
<div class='desc adjustable-font-size'>{description}</div>
</Fragment>
) }
{ actions && <ArticleActions actions={actions} /> }
</div>
{ isFooter
? <ArticleFooter lang={lang} title={articleTitle} items={suggestedArticles} />
: <ArticleBody content={content} />
Expand Down Expand Up @@ -163,21 +177,23 @@ const ArticleInner = ({ lang, articleTitle, initialSubTitle }) => {
articleHistory.add(lang, articleTitle)
}, [])

const actions = currentSection === 0 ? [
{ name: 'sections', enabled: true, handler: showArticleTocPopup },
{ name: 'quickfacts', enabled: !!article.infobox, handler: showQuickFacts },
{ name: 'gallery', enabled: !!article.media.length, handler: showGallery },
{ name: 'languages', enabled: article.languageCount, handler: showArticleLanguagePopup }
] : null

return (
<div class={'article' + (section.isFooter ? ' footer' : '')} ref={containerRef}>
<ArticleSection
key={currentSection}
lang={lang}
{...section}
articleTitle={articleTitle}
hasActions={currentSection === 0}
hasInfobox={!!article.infobox}
hasGallery={!!article.media.length}
actions={actions}
references={article.references}
suggestedArticles={article.suggestedArticles}
showToc={showArticleTocPopup}
showQuickFacts={showQuickFacts}
showGallery={showGallery}
goToSubpage={goToArticleSubpage}
page={currentPage}
/>
Expand Down
2 changes: 1 addition & 1 deletion src/components/ArticleMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export const ArticleMenu = ({
// add Language Section item
if (hasLanguages) {
items.push({
title: i18n.i18n('menu-language'),
title: i18n.i18n('article-action-languages'),
action: onLanguageSelected
})
}
Expand Down
91 changes: 54 additions & 37 deletions style/article.less
Original file line number Diff line number Diff line change
Expand Up @@ -19,74 +19,91 @@
// This prevents long words like URLs from overflowing
// onto the next column.
word-wrap: break-word;

.lead-image {
margin-top: -10px;
width: 100%;
height: 100%;
background-size: 100% auto;
background-repeat: no-repeat;
}
background-size: cover;
background-position: center;
background-repeat: no-repeat;

.card {
padding: 10px;
border-radius: 5px;
background-color: #fff;
box-shadow: -2px 2px 10px 0 rgba( 0, 0, 0, 0.1 );
border: solid 1px #f5f5f5;
margin: 15px 5px;

&.with-image {
margin-top: -160px;
}
margin: 15px 5px 0 5px;
opacity: 0.85;

.title {
font-family: @titleFont;
font-size: 22px;
line-height: 20px;
line-height: 28px;

&.clamp {
max-height: 140px;
overflow: hidden;
position: relative;
margin-right: -1em;
padding-right: 1em;

&:before {
content: '...';
position: absolute;
right: 1em;
bottom: 0;
background: #fff;
}

&:after {
content: '';
position: absolute;
right: 1em;
width: 1em;
height: 1em;
margin-top: 0.2em;
background: #fff;
}
}
}

.desc {
font-family: @textFont;
font-size: 12px;
line-height: 19px;
margin-top: 5px;
color: @colorLight;
}

.line {
width: 63px;
height: 1px;
background-color: #c8ccd1;
margin-top: 10px;
color: #323438;
}

.article-actions {
display: flex;
margin-top: 15px;
justify-content: space-around;
margin-top: 12px;

&-button {
text-align: center;
flex: auto;
flex-basis: -moz-max-content;
display: flex;
flex-direction: row;
align-items: center;
padding: 4px;

img {
width: 24px;
height: 24px;
padding: 4px;
}

label {
display: inline-block;
color: #36c;
font-size: @smallFont;
}

img {
width: 55px;
height: 55px;
padding: 4px;
font-weight: bold;
display: none;
}

&[ data-selected='true' ] {
img {
-moz-outline-radius: 2px;
outline: solid 1px rgba( 51, 102, 204, 0.5 );
background-color: #eaf3ff;
-moz-outline-radius: 16px;
border-radius: 16px;
outline: solid 1px rgba( 51, 102, 204, 0.5 );
background-color: #eaf3ff;

label {
display: inline;
}
}
}
Expand Down

0 comments on commit 8580e42

Please sign in to comment.