import java.io.IOException;
import java.net.URL;
import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Collections;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-import java.util.TreeMap;
import be.nikiroo.fanfix.Instance;
import be.nikiroo.fanfix.data.MetaData;
*/
public abstract Image getCover(String luid) throws IOException;
- // TODO: ensure it is the main used interface
+ /**
+ * Retrieve the list of {@link MetaData} known by this {@link BasicLibrary}
+ * in a easy-to-filter version.
+ *
+ * @param pg
+ * the optional {@link Progress}
+ * @return the list of {@link MetaData} as a {@link MetaResultList} you can
+ * query
+ * @throws IOException
+ * in case of I/O eror
+ */
public MetaResultList getList(Progress pg) throws IOException {
+ // TODO: ensure it is the main used interface
+
return new MetaResultList(getMetas(pg));
}
- // TODO: make something for (normal and custom) not-story covers
+ // TODO: make something for (normal and custom) non-story covers
/**
* Return the cover image associated to this source.
}
/**
+ * @return the same as getList()
+ * @throws IOException
+ * in case of I/O error
* @deprecated please use {@link BasicLibrary#getList()} and
* {@link MetaResultList#getSources()} instead.
*/
}
/**
+ * @return the same as getList()
+ * @throws IOException
+ * in case of I/O error
* @deprecated please use {@link BasicLibrary#getList()} and
* {@link MetaResultList#getSourcesGrouped()} instead.
*/
}
/**
+ * @return the same as getList()
+ * @throws IOException
+ * in case of I/O error
* @deprecated please use {@link BasicLibrary#getList()} and
* {@link MetaResultList#getAuthors()} instead.
*/
}
/**
+ * @return the same as getList()
+ * @throws IOException
+ * in case of I/O error
* @deprecated please use {@link BasicLibrary#getList()} and
* {@link MetaResultList#getAuthorsGrouped()} instead.
*/
+ @Deprecated
public Map<String, List<String>> getAuthorsGrouped() throws IOException {
return getList().getAuthorsGrouped();
}
pg.done();
}
+
+ /**
+ * Describe a {@link Story} from its {@link MetaData} and return a list of
+ * title/value that represent this {@link Story}.
+ *
+ * @param meta
+ * the {@link MetaData} to represent
+ *
+ * @return the information, translated and sorted
+ */
+ static public Map<String, String> getMetaDesc(MetaData meta) {
+ Map<String, String> metaDesc = new LinkedHashMap<String, String>();
+
+ // TODO: i18n
+
+ StringBuilder tags = new StringBuilder();
+ for (String tag : meta.getTags()) {
+ if (tags.length() > 0) {
+ tags.append(", ");
+ }
+ tags.append(tag);
+ }
+
+ // TODO: i18n
+ metaDesc.put("Author", meta.getAuthor());
+ metaDesc.put("Published on", meta.getPublisher());
+ metaDesc.put("Publication date", meta.getDate());
+ metaDesc.put("Creation date", meta.getCreationDate());
+ String count = "";
+ if (meta.getWords() > 0) {
+ count = StringUtils.formatNumber(meta.getWords());
+ }
+ if (meta.isImageDocument()) {
+ metaDesc.put("Number of images", count);
+ } else {
+ metaDesc.put("Number of words", count);
+ }
+ metaDesc.put("Source", meta.getSource());
+ metaDesc.put("Subject", meta.getSubject());
+ metaDesc.put("Language", meta.getLang());
+ metaDesc.put("Tags", tags.toString());
+ metaDesc.put("URL", meta.getUrl());
+
+ return metaDesc;
+ }
}
// set options
String optionName = params.get("optionName");
if (optionName != null && !optionName.isEmpty()) {
+ String optionNo = params.get("optionNo");
String optionValue = params.get("optionValue");
- if (optionValue == null || optionValue.isEmpty()) {
+ if (optionNo != null || optionValue == null
+ || optionValue.isEmpty()) {
session.getCookies().delete(optionName);
cookies.remove(optionName);
} else {
appendPreHtml(builder, true);
+ Map<String, String> params = session.getParms();
+
String filter = cookies.get("filter");
+ if (params.get("optionNo") != null)
+ filter = null;
if (filter == null) {
filter = "";
}
- Map<String, String> params = session.getParms();
String browser = params.get("browser") == null ? ""
: params.get("browser");
String browser2 = params.get("browser2") == null ? ""
// TODO: javascript in realtime, using visible=false + hide [submit]
builder.append("<div class='filter'>\n");
- builder.append("\tFilter: \n");
+ builder.append("\t<span class='label'>Filter: </span>\n");
builder.append(
"\t<input name='optionName' type='hidden' value='filter' />\n");
builder.append("\t<input name='optionValue' type='text' value='"
+ filter + "' place-holder='...' />\n");
+ builder.append("\t<input name='optionNo' type='submit' value='x' />");
builder.append(
"\t<input name='submit' type='submit' value='Filter' />\n");
builder.append("</div>\n");
// 1-based (0 = desc)
int chapter = 0;
if (chapterStr != null && !"cover".equals(chapterStr)
- && !"metadata".equals(chapterStr) && !"json".equals(chapterStr)) {
+ && !"metadata".equals(chapterStr)
+ && !"json".equals(chapterStr)) {
try {
chapter = Integer.parseInt(chapterStr);
if (chapter < 0) {
if (img != null) {
in = img.newInputStream();
}
+ // TODO: get correct image type
+ mimeType = "image/png";
} else if ("metadata".equals(chapterStr)) {
MetaData meta = meta(luid, whitelist);
JSONObject json = JsonIO.toJson(meta);
mimeType = "application/json";
in = new ByteArrayInputStream(json.toString().getBytes());
- } else if ("json".equals(chapterStr)) {
+ } else if ("json".equals(chapterStr)) {
Story story = story(luid, whitelist);
JSONObject json = JsonIO.toJson(story);
mimeType = "application/json";
StringBuilder builder = new StringBuilder();
appendPreHtml(builder, false);
- if (chapter < 0) {
- builder.append(story);
- } else {
- if (chapter == 0) {
- // TODO: description
- chapter = 1;
- }
+ // For images documents, always go to the images if not chap 0 desc
+ if (story.getMeta().isImageDocument()) {
+ if (chapter > 0 && paragraph <= 0)
+ paragraph = 1;
+ }
- Chapter chap = null;
+ Chapter chap = null;
+ if (chapter <= 0) {
+ chap = story.getMeta().getResume();
+ } else {
try {
chap = story.getChapters().get(chapter - 1);
} catch (IndexOutOfBoundsException e) {
return NanoHTTPD.newFixedLengthResponse(Status.NOT_FOUND,
NanoHTTPD.MIME_PLAINTEXT, "Chapter not found");
}
+ }
- if (story.getMeta().isImageDocument() && paragraph <= 0) {
- paragraph = 1;
+ String first, previous, next, last;
+
+ StringBuilder content = new StringBuilder();
+
+ String disabledLeft = "";
+ String disabledRight = "";
+ String disabledZoomReal = "";
+ String disabledZoomWidth = "";
+ String disabledZoomHeight = "";
+
+ if (paragraph <= 0) {
+ first = getViewUrl(luid, 0, null);
+ previous = getViewUrl(luid, (Math.max(chapter - 1, 0)), null);
+ next = getViewUrl(luid,
+ (Math.min(chapter + 1, story.getChapters().size())),
+ null);
+ last = getViewUrl(luid, story.getChapters().size(), null);
+
+ StringBuilder desc = new StringBuilder();
+
+ if (chapter <= 0) {
+ desc.append("<h1 class='title'>");
+ desc.append(story.getMeta().getTitle());
+ desc.append("</h1>\n");
+ desc.append("<div class='desc'>\n");
+ desc.append("\t<div class='cover'>\n");
+ desc.append("\t\t<img src='/story/" + luid + "/cover'/>\n");
+ desc.append("\t</div>\n");
+ desc.append("\t<table class='details'>\n");
+ Map<String, String> details = BasicLibrary
+ .getMetaDesc(story.getMeta());
+ for (String key : details.keySet()) {
+ appendTableRow(desc, 2, key, details.get(key));
+ }
+ desc.append("\t</table>\n");
+ desc.append("</div>\n");
+ desc.append("<h1 class='title'>Description</h1>\n");
}
- String first, previous, next, last;
- String content;
+ content.append("<div class='viewer text'>\n");
+ content.append(desc);
+ String description = new TextOutput(false).convert(chap,
+ chapter > 0);
+ content.append(chap.getParagraphs().size() <= 0
+ ? "No content provided."
+ : description);
+ content.append("</div>\n");
+
+ if (chapter <= 0)
+ disabledLeft = " disabled='disbaled'";
+ if (chapter >= story.getChapters().size())
+ disabledRight = " disabled='disbaled'";
+ } else {
+ first = getViewUrl(luid, chapter, 1);
+ previous = getViewUrl(luid, chapter,
+ (Math.max(paragraph - 1, 1)));
+ next = getViewUrl(luid, chapter,
+ (Math.min(paragraph + 1, chap.getParagraphs().size())));
+ last = getViewUrl(luid, chapter, chap.getParagraphs().size());
+
+ if (paragraph <= 1)
+ disabledLeft = " disabled='disbaled'";
+ if (paragraph >= chap.getParagraphs().size())
+ disabledRight = " disabled='disbaled'";
+
+ // First -> previous *chapter*
+ if (chapter > 0)
+ disabledLeft = "";
+ first = getViewUrl(luid, (Math.max(chapter - 1, 0)), null);
+ if (paragraph <= 1) {
+ previous = first;
+ }
- if (paragraph <= 0) {
- first = getViewUrl(luid, 1, null);
- previous = getViewUrl(luid, (Math.max(chapter - 1, 1)),
- null);
- next = getViewUrl(luid,
- (Math.min(chapter + 1, story.getChapters().size())),
- null);
- last = getViewUrl(luid, story.getChapters().size(), null);
-
- content = "<div class='viewer text'>\n"
- + new TextOutput(false).convert(chap, true)
- + "</div>\n";
- } else {
- first = getViewUrl(luid, chapter, 1);
- previous = getViewUrl(luid, chapter,
- (Math.max(paragraph - 1, 1)));
- next = getViewUrl(luid, chapter, (Math.min(paragraph + 1,
- chap.getParagraphs().size())));
- last = getViewUrl(luid, chapter,
- chap.getParagraphs().size());
-
- Paragraph para = null;
- try {
- para = chap.getParagraphs().get(paragraph - 1);
- } catch (IndexOutOfBoundsException e) {
- return NanoHTTPD.newFixedLengthResponse(
- Status.NOT_FOUND, NanoHTTPD.MIME_PLAINTEXT,
- "Paragraph not found");
- }
+ Paragraph para = null;
+ try {
+ para = chap.getParagraphs().get(paragraph - 1);
+ } catch (IndexOutOfBoundsException e) {
+ return NanoHTTPD.newFixedLengthResponse(Status.NOT_FOUND,
+ NanoHTTPD.MIME_PLAINTEXT,
+ "Paragraph " + paragraph + " not found");
+ }
- if (para.getType() == ParagraphType.IMAGE) {
- String zoomStyle = "max-width: 100%;";
- String zoomOption = cookies.get("zoom");
- if (zoomOption != null && !zoomOption.isEmpty()) {
- if (zoomOption.equals("real")) {
- zoomStyle = "";
- } else if (zoomOption.equals("width")) {
- zoomStyle = "max-width: 100%;";
- } else if (zoomOption.equals("height")) {
- // see height of navbar + optionbar
- zoomStyle = "max-height: calc(100% - 128px);";
- }
+ if (para.getType() == ParagraphType.IMAGE) {
+ String zoomStyle = "max-width: 100%;";
+ disabledZoomWidth = " disabled='disabled'";
+ String zoomOption = cookies.get("zoom");
+ if (zoomOption != null && !zoomOption.isEmpty()) {
+ if (zoomOption.equals("real")) {
+ zoomStyle = "";
+ disabledZoomWidth = "";
+ disabledZoomReal = " disabled='disabled'";
+ } else if (zoomOption.equals("width")) {
+ zoomStyle = "max-width: 100%;";
+ } else if (zoomOption.equals("height")) {
+ // see height of navbar + optionbar
+ zoomStyle = "max-height: calc(100% - 128px);";
+ disabledZoomWidth = "";
+ disabledZoomHeight = " disabled='disabled'";
}
- content = String.format("" //
- + "<a class='viewer link' href='%s'>" //
- + "<img class='viewer img' style='%s' src='%s'/>"
- + "</a>", //
- next, //
- zoomStyle, //
- getStoryUrl(luid, chapter, paragraph));
- } else {
- content = para.getContent();
}
+ content.append(String.format("" //
+ + "<a class='viewer link' href='%s'>"
+ + "<img class='viewer img' style='%s' src='%s'/>"
+ + "</a>", //
+ next, //
+ zoomStyle, //
+ getStoryUrl(luid, chapter, paragraph)));
+ } else {
+ content.append(String.format("" //
+ + "<div class='viewer text'>%s</div>", //
+ para.getContent()));
}
+ }
- builder.append(String.format("" //
- + "<div class='bar navbar'>\n" //
- + "\t<a class='button first' href='%s'><<</a>\n"//
- + "\t<a class='button previous' href='%s'><</a>\n"//
- + "\t<a class='button next' href='%s'>></a>\n"//
- + "\t<a class='button last' href='%s'>>></a>\n"//
- + "</div>\n" //
- + "%s", //
- first, //
- previous, //
- next, //
- last, //
- content //
- ));
-
- builder.append("<div class='bar optionbar ");
- if (paragraph > 0) {
- builder.append("s4");
- } else {
- builder.append("s1");
+ builder.append(String.format("" //
+ + "<div class='bar navbar'>\n" //
+ + "\t<a%s class='button first' href='%s'><<</a>\n"//
+ + "\t<a%s class='button previous' href='%s'><</a>\n" //
+ + "\t<div class='gotobox itemsbox'>\n" //
+ + "\t\t<div class='button goto'>%d</div>\n" //
+ + "\t\t<div class='items goto'>\n", //
+ disabledLeft, first, //
+ disabledLeft, previous, //
+ paragraph > 0 ? paragraph : chapter //
+ ));
+
+ // List of chap/para links
+
+ String blink = "/view/story/" + luid + "/";
+ appendItemA(builder, 3, blink + "0", "Description",
+ paragraph == 0 && chapter == 0);
+
+ if (paragraph > 0) {
+ blink = blink + chapter + "/";
+ for (int i = 1; i <= chap.getParagraphs().size(); i++) {
+ appendItemA(builder, 3, blink + i, "Image " + i,
+ paragraph == i);
}
- builder.append("'>\n");
- builder.append(
- " <a class='button back' href='/'>BACK</a>\n");
-
- if (paragraph > 0) {
- builder.append(String.format("" //
- + "\t<a class='button zoomreal' href='%s'>REAL</a>\n"//
- + "\t<a class='button zoomwidth' href='%s'>WIDTH</a>\n"//
- + "\t<a class='button zoomheight' href='%s'>HEIGHT</a>\n"//
- + "</div>\n", //
- uri + "?optionName=zoom&optionValue=real", //
- uri + "?optionName=zoom&optionValue=width", //
- uri + "?optionName=zoom&optionValue=height" //
- ));
+ } else {
+ int i = 1;
+ for (Chapter c : story.getChapters()) {
+ String chapName = "Chapter " + c.getNumber();
+ if (c.getName() != null && !c.getName().isEmpty()) {
+ chapName += ": " + c.getName();
+ }
+
+ appendItemA(builder, 3, blink + i, chapName, chapter == i);
+
+ i++;
}
}
+ builder.append(String.format("" //
+ + "\t\t</div>\n" //
+ + "\t</div>\n" //
+ + "\t<a%s class='button next' href='%s'>></a>\n" //
+ + "\t<a%s class='button last' href='%s'>>></a>\n"//
+ + "</div>\n", //
+ disabledRight, next, //
+ disabledRight, last //
+ ));
+
+ builder.append(content);
+
+ builder.append("<div class='bar optionbar ");
+ if (paragraph > 0) {
+ builder.append("s4");
+ } else {
+ builder.append("s1");
+ }
+ builder.append("'>\n");
+ builder.append(" <a class='button back' href='/'>BACK</a>\n");
+
+ if (paragraph > 0) {
+ builder.append(String.format("" //
+ + "\t<a%s class='button zoomreal' href='%s'>REAL</a>\n"//
+ + "\t<a%s class='button zoomwidth' href='%s'>WIDTH</a>\n"//
+ + "\t<a%s class='button zoomheight' href='%s'>HEIGHT</a>\n"//
+ + "</div>\n", //
+ disabledZoomReal,
+ uri + "?optionName=zoom&optionValue=real", //
+ disabledZoomWidth,
+ uri + "?optionName=zoom&optionValue=width", //
+ disabledZoomHeight,
+ uri + "?optionName=zoom&optionValue=height" //
+ ));
+ }
+
appendPostHtml(builder);
return NanoHTTPD.newFixedLengthResponse(Status.OK,
NanoHTTPD.MIME_HTML, builder.toString());
throws IOException {
MetaData meta = meta(luid, whitelist);
if (meta != null) {
- return meta.getCover();
+ BasicLibrary lib = Instance.getInstance().getLibrary();
+ return lib.getCover(meta.getLuid());
}
return null;
if (banner) {
builder.append("<div class='banner'>\n");
- builder.append("\t<img class='ico' src='") //
+ builder.append("\t<img class='ico' src='/") //
.append(favicon) //
.append("'/>\n");
builder.append("\t<h1>Fanfix</h1>\n");
}
builder.append(">").append(name).append("</option>\n");
}
+
+ private void appendTableRow(StringBuilder builder, int depth,
+ String... tds) {
+ for (int i = 0; i < depth; i++) {
+ builder.append("\t");
+ }
+
+ int col = 1;
+ builder.append("<tr>");
+ for (String td : tds) {
+ builder.append("<td class='col");
+ builder.append(col++);
+ builder.append("'>");
+ builder.append(td);
+ builder.append("</td>");
+ }
+ builder.append("</tr>\n");
+ }
+
+ private void appendItemA(StringBuilder builder, int depth, String link,
+ String name, boolean selected) {
+ for (int i = 0; i < depth; i++) {
+ builder.append("\t");
+ }
+
+ builder.append("<a href='");
+ builder.append(link);
+ builder.append("' class='item goto");
+ if (selected) {
+ builder.append(" selected");
+ }
+ builder.append("'>");
+ builder.append(name);
+ builder.append("</a>\n");
+ }
+
+ public static void main(String[] args) throws IOException {
+ Instance.init();
+ WebLibraryServer web = new WebLibraryServer(false);
+ web.run();
+ }
}
+/*
+ * #AAA391: main gray
+ * #555C7E: reverse main
+ *
+ * #bac2e1: button border
+ * #DCE4F3: button hover
+ *
+ * #ddffdd: background pastel green
+ * #88dd88: for border
+ *
+ * #ffdddd: pastel red
+ * #dd8888: for border
+ *
+ */
+
html, body, .main {
margin: 0;
padding: 0;
- font-family : Verdana, "Bitstream Vera Sans", "DejaVu Sans", Tahoma, Geneva, Arial, Sans-serif;
+ font-family: Verdana, "Bitstream Vera Sans", "DejaVu Sans", Tahoma, Geneva, Arial, Sans-serif;
font-size: 12px;
- DISABLED_color: #635c4a;
height: 100%;
}
-table {
- width: 100%;
-}
-
.banner {
}
}
.main {
- display: block;
+ margin: auto;
}
.message {
- background-color: #ddffdd;
- border: 1px solid #88dd88;
- clear: left;
- border-radius: 5px;
- padding: 5px;
- margin: 10px;
+ background-color: #ddffdd;
+ border: 1px solid #88dd88;
+ clear: left;
+ border-radius: 5px;
+ padding: 5px;
+ margin: 10px;
}
.error {
- background-color: #ffdddd;
- border: 1px solid #dd8888;
- clear: left;
- border-radius: 5px;
- padding: 5px;
- margin: 10px;
+ background-color: #ffdddd;
+ border: 1px solid #dd8888;
+ clear: left;
+ border-radius: 5px;
+ padding: 5px;
+ margin: 10px;
}
/* all links and clickable should show a pointer cursor */
cursor: pointer;
}
-a:hover {
+a:not(.selected):hover {
background-color: rgb(225, 225, 225);
}
margin-left: 20px;
}
+.itemsbox .items {
+ display: block;
+ position: absolute;
+ overflow-y: auto;
+
+ transition: all 0.5s ease;
+ visibility: hidden;
+ opacity: 0;
+}
+
+.itemsbox:hover .items, .itemsbox .items:hover {
+ visibility: visible;
+ opacity: 1;
+}
+
+.itemsbox .items .item {
+ display: block;
+ padding: 5px;
+ color: black;
+ cursor: pointer;
+ text-decoration: none;
+}
+
+.itemsbox .items .item.selected {
+ font-weight: bold;
+ cursor: default;
+}
+
+.itemsbox .items .item:not(.selected):hover, .button:hover {
+ background-color: #DCE4F3;
+}
+
+.itemsbox .items .item[disabled], .button[disabled] {
+ pointer-events: none;
+ background-color: #aaa;
+ filter: grayscale(100%);
+ border-color: #AAA391;
+}
+
+.button {
+ display: inline-block;
+ text-align: center;
+ text-decoration: none;
+ background-position: center;
+ background-repeat: no-repeat;
+ border: 1px solid #bac2e1;
+ border-radius: 5px;
+}
+
.login {
width: 250px;
display: flex;
margin: auto;
- margin-top: 200px;
+ margin-top: 100px;
flex-direction: column;
- border: 1px solid gray;
+ border: 1px solid #AAA391;
padding: 20px;
border-radius: 10px;
}
}
.filter {
- padding: 10px;
+ padding: 5px;
+ height: 36px;
+ border: 1px solid #AAA391;
+ border-radius: 5px;
+ margin-top: 5px;
+ margin-bottom: 5px;
+ display: flex;
+}
+
+.filter > * {
+ height: 36px;
+ display: inline-block;
+}
+
+.filter .label {
+ line-height: 36px;
+ padding-right: 5px;
+}
+
+.filter input[type='text'] {
+ height: 32px;
+ padding: 0;
+ margin: 0;
+ border-width: 2px;
+ min-width: 50px;
+ flex-grow: 100;
+ flex-shrink: 100;
+}
+
+.filter input[name='optionNo'] {
+ background-image: url('/clear-32x32.png');
+ color: transparent;
+ width: 36px;
}
.books {
.book_line .link, .book_line .title {
flex-grow: 100;
- padding-right: 5px;
- padding-left: 5px;
+ padding: 5px;
}
.book_line .link {
}
.book_line .luid {
- color: gray;
+ color: #AAA391;
padding-right: 10px;
padding-left: 10px;
}
display: block;
background: white;
position: fixed;
+ margin: auto;
}
+.bar.navbar { padding-left: calc(50% - (5 * (64px + 5px) / 2)); }
+
+.bar.optionbar.s1 { padding-left: calc(50% - (1 * (64px + 5px) / 2)); }
+.bar.optionbar.s4 { padding-left: calc(50% - (4 * (64px + 5px) / 2)); }
+
+.bar.optionbar {
+ bottom: 0;
+}
+
+.bar .button {
+ height: 54px;
+ width: 54px;
+ line-height: 54px;
+ margin: 5px;
+}
+
+.bar .gotobox {
+ display: inline-block;
+}
+
+.bar .gotobox .items {
+ background-color: white;
+ border: 1px solid gray;
+ border-radius: 5px;
+ width: 196px;
+ margin: -5px;
+ margin-left: -66px;
+ max-height: 400px;
+}
+
+.bar .button.first { color: transparent; background-image: url('/arrow_double_left-32x32.png'); }
+.bar .button.previous { color: transparent; background-image: url('/arrow_left-32x32.png'); }
+.bar .button.next { color: transparent; background-image: url('/arrow_right-32x32.png'); }
+.bar .button.last { color: transparent; background-image: url('/arrow_double_right-32x32.png'); }
+
+.bar .button.back { color: transparent; background-image: url('/back-32x32.png'); }
+.bar .button.zoomreal { color: transparent; background-image: url('/actual_size-32x32.png'); }
+.bar .button.zoomwidth { color: transparent; background-image: url('/fit_to_width-32x32.png'); }
+.bar .button.zoomheight { color: transparent; background-image: url('/fit_to_height-32x32.png'); }
+
.viewer {
padding-top: 64px;
padding-bottom: 64px;
}
+.viewer .title {
+ background-color: #AAA391;
+ text-align: center;
+ font-variant: small-caps;
+ color: white;
+}
+
+.viewer.img {
+ margin: auto;
+ display: block;
+}
+
a.viewer.link:hover {
background-color: transparent;
}
padding-right: 10px;
}
-.bar.navbar {
- padding-left: calc(50% - (4 * 64px / 2));
+.desc {
+ display: flex;
+ flex-direction: column;
+ padding-top: 10px;
}
-.bar.optionbar {
- bottom: 0;
+.desc .cover {
+ max-height: 280px;
+ overflow: hidden;
}
-.bar.optionbar.s1 {
- padding-left: calc(50% - (1 * 64px / 2));
+.desc .cover img {
+ max-width: 80%;
+ margin: auto;
+ display: block;
}
-.bar.optionbar.s4 {
- padding-left: calc(50% - (4 * 64px / 2));
+.desc .details .col1 {
+ font-weight: bold;
+ padding-left: 5px;
+ padding-right: 5px;
}
-.bar .button {
- height: 54px;
- width: 54px;
- line-height: 64px;
- display: inline-block;
- text-align: center;
- color: transparent;
- text-decoration: none;
- background-position: center;
- background-repeat: no-repeat;
- border-radius: 5px;
- border: 1px solid #bac2e1;
- margin: 5px;
+.desc .details .col2 {
+ color: #AAA391;
}
-.bar .button:hover {
- background-color: bac2e1;
+@media(min-width: 800px) {
+ .main {
+ max-width: 800px;
+ }
+
+ .bar.navbar { padding-left: calc(400px - (5 * (64px + 5px) / 2)); }
+
+ .bar.optionbar.s1 { padding-left: calc(400px - (1 * (64px + 5px) / 2)); }
+ .bar.optionbar.s4 { padding-left: calc(400px - (4 * (64px + 5px) / 2)); }
+
+ .desc { flex-direction: row; }
+ .desc .cover img {
+ width: 200px;
+ padding-right: 10px;
+ }
}
-
-.bar .button.first { background-image: url('/arrow_double_left-32x32.png'); }
-.bar .button.previous { background-image: url('/arrow_left-32x32.png'); }
-.bar .button.next { background-image: url('/arrow_right-32x32.png'); }
-.bar .button.last { background-image: url('/arrow_double_right-32x32.png'); }
-
-.bar .button.back { background-image: url('/back-32x32.png'); }
-.bar .button.zoomreal { background-image: url('/actual_size-32x32.png'); }
-.bar .button.zoomwidth { background-image: url('/fit_to_width-32x32.png'); }
-.bar .button.zoomheight { background-image: url('/fit_to_height-32x32.png'); }