/* * CatSaver * Copyright (C) 2015 HiHex Ltd. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * this program. If not, see <http://www.gnu.org/licenses/>. */ package hihex.cs; import android.content.Context; import android.content.res.Resources; import android.text.format.DateUtils; import android.text.format.Formatter; import com.google.common.eventbus.Subscribe; import com.x5.template.Chunk; import com.x5.template.ContentSource; import com.x5.template.Snippet; import com.x5.template.Theme; import com.x5.template.filters.BasicFilter; import com.x5.template.filters.FilterArgs; import com.x5.template.providers.AndroidTemplates; import java.util.HashMap; /** * Customized Chunk template theme. */ public final class ChunkTheme { private ChunkTheme() {} /** Chunk filter to convert number of bytes to readable file size. */ private static final class FileSizeFilter extends BasicFilter { private final Context mContext; public FileSizeFilter(final Context context) { mContext = context; } @Override public String transformText(final Chunk chunk, final String text, final FilterArgs args) { try { final long fileSize = Long.parseLong(text); return Formatter.formatShortFileSize(mContext, fileSize); } catch (final NumberFormatException e) { return text; } } @Override public String getFilterName() { return "file_size"; } } /** Chunk filter to convert number of milliseconds since the epoch to a relative number to now. */ private static final class RelativeTimeFilter extends BasicFilter { private final Context mContext; public RelativeTimeFilter(final Context context) { mContext = context; } @Override public String transformText(final Chunk chunk, final String text, final FilterArgs args) { try { final long milliseconds = Long.parseLong(text); final long transition = 3 * DateUtils.DAY_IN_MILLIS; final CharSequence relTime = DateUtils.getRelativeDateTimeString(mContext, milliseconds, 0, transition, 0); return relTime.toString(); } catch (final NumberFormatException e) { return text; } } @Override public String getFilterName() { return "relative_time"; } } private static final class ResourceContentSource implements ContentSource { private final Resources mResources; private final String mPackageName; private final HashMap<String, Integer> mCachedIds = new HashMap<>(); public ResourceContentSource(final Context context) { mResources = context.getResources(); mPackageName = context.getPackageName(); } @Override public String fetch(final String itemName) { final int id = getId(itemName); if (id != 0) { return mResources.getString(id); } else { return '«' + itemName + '»'; } } @Override public boolean provides(String itemName) { return true; } @Override public String getProtocol() { return "r"; } @Override public Snippet getSnippet(String snippetName) { return null; } private int getId(final String itemName) { final Integer cachedId = mCachedIds.get(itemName); if (cachedId != null) { return cachedId; } final int id = mResources.getIdentifier("chunk_" + itemName, "string", mPackageName); mCachedIds.put(itemName, id); return id; } } private static final class FaviconSource implements ContentSource { private int mVersion = 0; @Override public String fetch(final String itemName) { return String.valueOf(mVersion); } @Override public boolean provides(String itemName) { return true; } @Override public String getProtocol() { return "favicon"; } @Override public Snippet getSnippet(String snippetName) { return null; } @Subscribe public void updateIp(final Events.UpdateIpAddress ev) { mVersion += 1; } } /** Creates a customized Chunk theme. */ public static Theme create(final Context context) { final AndroidTemplates provider = new AndroidTemplates(context); final Theme theme = new Theme(provider); theme.registerFilter(new FileSizeFilter(context)); theme.registerFilter(new RelativeTimeFilter(context)); theme.addProtocol(new ResourceContentSource(context)); final FaviconSource faviconSource = new FaviconSource(); Events.bus.register(faviconSource); theme.addProtocol(faviconSource); return theme; } }