diff --git a/app/build.gradle b/app/build.gradle
index 9e492f1a3c9..2bd90315197 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -143,6 +143,8 @@ dependencies {
compile "org.jsoup:jsoup:${JSOUP}"
+ compile "com.squareup.okhttp3:okhttp:${OKHTTP}"
+
compile "com.github.bumptech.glide:glide:${GLIDE}"
kapt "com.github.bumptech.glide:compiler:${GLIDE}"
@@ -158,4 +160,8 @@ dependencies {
compile("com.crashlytics.sdk.android:crashlytics:${CRASHLYTICS}@aar") {
transitive = true;
}
+
+ compile "com.davemorrissey.labs:subsampling-scale-image-view:${SCALE_IMAGE_VIEW}"
+
+ compile "com.sothree.slidinguppanel:library:${SLIDING_PANEL}"
}
\ No newline at end of file
diff --git a/app/src/debug/res/xml/file_paths.xml b/app/src/debug/res/xml/file_paths.xml
new file mode 100644
index 00000000000..087f23c994e
--- /dev/null
+++ b/app/src/debug/res/xml/file_paths.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 90f2d3b3cb8..1ae569ed39b 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -33,26 +33,26 @@
+ android:theme="@style/FrostTheme.Overlay.Slide" />
+ android:theme="@style/FrostTheme.Overlay.Slide">
@@ -107,17 +107,20 @@
+
+
+
+
diff --git a/app/src/main/assets/adblock.txt b/app/src/main/assets/adblock.txt
new file mode 100644
index 00000000000..1d561271a22
--- /dev/null
+++ b/app/src/main/assets/adblock.txt
@@ -0,0 +1,2344 @@
+# Ad server list for use with hosts files to block ads
+#
+# For more information about this list, see: https://pgl.yoyo.org/adservers/
+# ----
+# last updated: Wed, 12 Jul 2017 13:54:58 GMT
+# entries: 2331
+# format: hosts (hosts -- in hosts file format)
+# credits: Peter Lowe - pgl@yoyo.org - https://pgl.yoyo.org/ - https://twitter.com/pgl
+# this URL: https://pgl.yoyo.org/adservers/serverlist.php?hostformat=hosts&mimetype=plaintext&useip=0.0.0.0
+# other formats: https://pgl.yoyo.org/adservers/formats.php
+# policy: https://pgl.yoyo.org/adservers/policy.php
+#
+# start date: Wed, 12 Jul 2017 00:00:00
+101com.com
+101order.com
+123found.com
+180hits.de
+180searchassistant.com
+207.net
+247media.com
+24log.com
+24log.de
+24pm-affiliation.com
+2mdn.net
+2o7.net
+360yield.com
+4affiliate.net
+4d5.net
+50websads.com
+518ad.com
+51yes.com
+600z.com
+777partner.com
+77tracking.com
+7bpeople.com
+7search.com
+99count.com
+a-ads.com
+a-counter.kiev.ua
+a.0day.kiev.ua
+a.aproductmsg.com
+a.collective-media.net
+a.consumer.net
+a.mktw.net
+a.sakh.com
+a.ucoz.net
+a.ucoz.ru
+a.xanga.com
+a32.g.a.yimg.com
+aaddzz.com
+abacho.net
+abc-ads.com
+absoluteclickscom.com
+abz.com
+ac.rnm.ca
+accounts.pkr.com.invalid
+acsseo.com
+actionsplash.com
+actualdeals.com
+acuityads.com
+ad-balancer.at
+ad-balancer.net
+ad-center.com
+ad-pay.de
+ad-rotator.com
+ad-server.gulasidorna.se
+ad-serverparc.nl
+ad-souk.com
+ad-space.net
+ad-tech.com
+ad-up.com
+ad.100.tbn.ru
+ad.71i.de
+ad.a8.net
+ad.abcnews.com
+ad.abctv.com
+ad.aboutwebservices.com
+ad.abum.com
+ad.afy11.net
+ad.allstar.cz
+ad.altervista.org
+ad.amgdgt.com
+ad.anuntis.com
+ad.auditude.com
+ad.bizo.com
+ad.bnmla.com
+ad.bondage.com
+ad.caradisiac.com
+ad.centrum.cz
+ad.cgi.cz
+ad.choiceradio.com
+ad.clix.pt
+ad.cooks.com
+ad.crwdcntrl.net
+ad.digitallook.com
+ad.directrev.com
+ad.doctissimo.fr
+ad.domainfactory.de
+ad.e-kolay.net
+ad.eurosport.com
+ad.f1cd.ru
+ad.flurry.com
+ad.foxnetworks.com
+ad.freecity.de
+ad.gate24.ch
+ad.globe7.com
+ad.grafika.cz
+ad.hbv.de
+ad.hodomobile.com
+ad.httpool.com
+ad.hyena.cz
+ad.iinfo.cz
+ad.ilove.ch
+ad.infoseek.com
+ad.jamba.net
+ad.jamster.co.uk
+ad.jetsoftware.com
+ad.keenspace.com
+ad.leadbolt.net
+ad.liveinternet.ru
+ad.lupa.cz
+ad.media-servers.net
+ad.mediastorm.hu
+ad.mgd.de
+ad.musicmatch.com
+ad.nachtagenten.de
+ad.nozonedata.com
+ad.nttnavi.co.jp
+ad.nwt.cz
+ad.onad.eu
+ad.pandora.tv
+ad.preferances.com
+ad.profiwin.de
+ad.prv.pl
+ad.rambler.ru
+ad.reunion.com
+ad.scanmedios.com
+ad.sensismediasmart.com.au
+ad.seznam.cz
+ad.simgames.net
+ad.slutload.com
+ad.smartclip.net
+ad.tbn.ru
+ad.technoratimedia.com
+ad.thewheelof.com
+ad.turn.com
+ad.tv2.no
+ad.twitchguru.com
+ad.usatoday.com
+ad.virtual-nights.com
+ad.wavu.hu
+ad.way.cz
+ad.weatherbug.com
+ad.wsod.com
+ad.wz.cz
+ad.yadro.ru
+ad.yourmedia.com
+ad.zanox.com
+ad0.bigmir.net
+ad01.mediacorpsingapore.com
+ad1.emediate.dk
+ad1.emule-project.org
+ad1.kde.cz
+ad1.pamedia.com.au
+ad2.iinfo.cz
+ad2.linxcz.cz
+ad2.lupa.cz
+ad2flash.com
+ad2games.com
+ad3.iinfo.cz
+ad3.pamedia.com.au
+ad4game.com
+adaction.de
+adadvisor.net
+adap.tv
+adapt.tv
+adbanner.ro
+adbard.net
+adbers.com
+adblade.com
+adblockanalytics.com
+adboost.de.vu
+adboost.net
+adbooth.net
+adbot.com
+adbrite.com
+adbroker.de
+adbunker.com
+adbutler.com
+adbutler.de
+adbuyer.com
+adbuyer3.lycos.com
+adcash.com
+adcast.deviantart.com
+adcell.de
+adcenter.mdf.se
+adcenter.net
+adcentriconline.com
+adcept.net
+adclick.com
+adclient.uimserv.net
+adclient1.tucows.com
+adcomplete.com
+adconion.com
+adcontent.gamespy.com
+adcycle.com
+add.newmedia.cz
+addealing.com
+addfreestats.com
+addme.com
+adecn.com
+ademails.com
+adengage.com
+adexchangeprediction.com
+adexpose.com
+adext.inkclub.com
+adf.ly
+adfactor.nl
+adfarm.mediaplex.com
+adflight.com
+adforce.com
+adform.com
+adgardener.com
+adgoto.com
+adgridwork.com
+adhese.be
+adhese.com
+adimage.asiaone.com.sg
+adimage.guardian.co.uk
+adimages.been.com
+adimages.carsoup.com
+adimages.go.com
+adimages.homestore.com
+adimages.omroepzeeland.nl
+adimages.sanomawsoy.fi
+adimg.cnet.com
+adimg.com.com
+adimg.uimserv.net
+adimg1.chosun.com
+adimgs.sapo.pt
+adimpact.com
+adinjector.net
+adinterax.com
+adisfy.com
+adition.com
+adition.de
+adition.net
+adizio.com
+adjix.com
+adjug.com
+adjuggler.com
+adjuggler.yourdictionary.com
+adjustnetwork.com
+adk2.com
+adk2ads.tictacti.com
+adland.ru
+adlantic.nl
+adledge.com
+adlegend.com
+adlog.com.com
+adloox.com
+adlooxtracking.com
+adlure.net
+admagnet.net
+admailtiser.com
+adman.gr
+adman.in.gr
+adman.otenet.gr
+admanagement.ch
+admanager.btopenworld.com
+admanager.carsoup.com
+admarketplace.net
+admarvel.com
+admax.nexage.com
+admedia.com
+admedia.ro
+admeld.com
+admerize.be
+admeta.com
+admex.com
+adminder.com
+adminshop.com
+admized.com
+admob.com
+admonitor.com
+admotion.com.ar
+adnet-media.net
+adnet.asahi.com
+adnet.biz
+adnet.de
+adnet.ru
+adnet.worldreviewer.com
+adnetinteractive.com
+adnetwork.net
+adnetworkperformance.com
+adnews.maddog2000.de
+adnotch.com
+adnxs.com
+adocean.pl
+adonspot.com
+adoperator.com
+adorigin.com
+adpepper.dk
+adpepper.nl
+adperium.com
+adpia.vn
+adplus.co.id
+adplxmd.com
+adprofile.net
+adprojekt.pl
+adq.nextag.com
+adrazzi.com
+adreactor.com
+adrecreate.com
+adremedy.com
+adreporting.com
+adres.internet.com
+adrevolver.com
+adriver.ru
+adrolays.de
+adrotate.de
+adrotator.se
+adrta.com
+ads-click.com
+ads.4tube.com
+ads.5ci.lt
+ads.abovetopsecret.com
+ads.aceweb.net
+ads.activestate.com
+ads.adfox.ru
+ads.administrator.de
+ads.adshareware.net
+ads.adultfriendfinder.com
+ads.adultswim.com
+ads.advance.net
+ads.adverline.com
+ads.affiliates.match.com
+ads.ak.facebook.com.edgesuite.net
+ads.allvatar.com
+ads.alt.com
+ads.amdmb.com
+ads.amigos.com
+ads.aol.co.uk
+ads.aol.com
+ads.apn.co.nz
+ads.appsgeyser.com
+ads.as4x.tmcs.net
+ads.as4x.tmcs.ticketmaster.com
+ads.asia1.com.sg
+ads.asiafriendfinder.com
+ads.ask.com
+ads.aspalliance.com
+ads.avazu.net
+ads.batpmturner.com
+ads.beenetworks.net
+ads.belointeractive.com
+ads.berlinonline.de
+ads.betanews.com
+ads.betfair.com
+ads.betfair.com.au
+ads.bigchurch.com
+ads.bigfoot.com
+ads.bing.com
+ads.bittorrent.com
+ads.blog.com
+ads.bloomberg.com
+ads.bluelithium.com
+ads.bluemountain.com
+ads.bluesq.com
+ads.bonniercorp.com
+ads.boylesports.com
+ads.brabys.com
+ads.brazzers.com
+ads.bumq.com
+ads.businessweek.com
+ads.canalblog.com
+ads.canoe.ca
+ads.casinocity.com
+ads.cbc.ca
+ads.cc
+ads.cc-dt.com
+ads.centraliprom.com
+ads.cgnetworks.com
+ads.channel4.com
+ads.clearchannel.com
+ads.co.com
+ads.com.com
+ads.contactmusic.com
+ads.contentabc.com
+ads.contextweb.com
+ads.crakmedia.com
+ads.creative-serving.com
+ads.creativematch.com
+ads.cricbuzz.com
+ads.cybersales.cz
+ads.dada.it
+ads.datinggold.com
+ads.datingyes.com
+ads.dazoot.ro
+ads.deltha.hu
+ads.dennisnet.co.uk
+ads.desmoinesregister.com
+ads.detelefoongids.nl
+ads.deviantart.com
+ads.digital-digest.com
+ads.digitalmedianet.com
+ads.digitalpoint.com
+ads.directionsmag.com
+ads.domain.com
+ads.domeus.com
+ads.eagletribune.com
+ads.easy-forex.com
+ads.eatinparis.com
+ads.economist.com
+ads.edbindex.dk
+ads.egrana.com.br
+ads.einmedia.com
+ads.electrocelt.com
+ads.elitetrader.com
+ads.emirates.net.ae
+ads.epltalk.com
+ads.eu.msn.com
+ads.exactdrive.com
+ads.expat-blog.biz
+ads.expedia.com
+ads.ezboard.com
+ads.factorymedia.com
+ads.fairfax.com.au
+ads.faxo.com
+ads.ferianc.com
+ads.filmup.com
+ads.financialcontent.com
+ads.flooble.com
+ads.fool.com
+ads.footymad.net
+ads.forbes.com
+ads.forbes.net
+ads.forium.de
+ads.fortunecity.com
+ads.fotosidan.se
+ads.foxkidseurope.net
+ads.foxnetworks.com
+ads.foxnews.com
+ads.freecity.de
+ads.friendfinder.com
+ads.ft.com
+ads.futurenet.com
+ads.gamecity.net
+ads.gamershell.com
+ads.gamespyid.com
+ads.gamigo.de
+ads.gaming-universe.de
+ads.gawker.com
+ads.geekswithblogs.net
+ads.glispa.com
+ads.gmodules.com
+ads.godlikeproductions.com
+ads.goyk.com
+ads.gplusmedia.com
+ads.gradfinder.com
+ads.grindinggears.com
+ads.groundspeak.com
+ads.gsm-exchange.com
+ads.gsmexchange.com
+ads.guardian.co.uk
+ads.guardianunlimited.co.uk
+ads.guru3d.com
+ads.hardwaresecrets.com
+ads.harpers.org
+ads.hbv.de
+ads.hearstmags.com
+ads.heartlight.org
+ads.heias.com
+ads.hideyourarms.com
+ads.hollywood.com
+ads.horsehero.com
+ads.horyzon-media.com
+ads.iafrica.com
+ads.ibest.com.br
+ads.ibryte.com
+ads.icq.com
+ads.ign.com
+ads.img.co.za
+ads.imgur.com
+ads.indiatimes.com
+ads.infi.net
+ads.internic.co.il
+ads.ipowerweb.com
+ads.isoftmarketing.com
+ads.itv.com
+ads.iwon.com
+ads.jewishfriendfinder.com
+ads.jiwire.com
+ads.jobsite.co.uk
+ads.jpost.com
+ads.jubii.dk
+ads.justhungry.com
+ads.kaktuz.net
+ads.kelbymediagroup.com
+ads.kinobox.cz
+ads.kinxxx.com
+ads.kompass.com
+ads.krawall.de
+ads.lesbianpersonals.com
+ads.linuxfoundation.org
+ads.linuxjournal.com
+ads.linuxsecurity.com
+ads.livenation.com
+ads.mariuana.it
+ads.massinfra.nl
+ads.mcafee.com
+ads.mediaodyssey.com
+ads.medienhaus.de
+ads.mgnetwork.com
+ads.mmania.com
+ads.moceanads.com
+ads.motor-forum.nl
+ads.motormedia.nl
+ads.msn.com
+ads.multimania.lycos.fr
+ads.nationalgeographic.com
+ads.ncm.com
+ads.netmechanic.com
+ads.networksolutions.com
+ads.newdream.net
+ads.newgrounds.com
+ads.newmedia.cz
+ads.newsint.co.uk
+ads.newsquest.co.uk
+ads.ninemsn.com.au
+ads.nj.com
+ads.nola.com
+ads.nordichardware.com
+ads.nordichardware.se
+ads.nwsource.com
+ads.nyi.net
+ads.nytimes.com
+ads.nyx.cz
+ads.nzcity.co.nz
+ads.o2.pl
+ads.oddschecker.com
+ads.okcimg.com
+ads.ole.com
+ads.olivebrandresponse.com
+ads.oneplace.com
+ads.ookla.com
+ads.optusnet.com.au
+ads.outpersonals.com
+ads.passion.com
+ads.pennet.com
+ads.penny-arcade.com
+ads.pheedo.com
+ads.phpclasses.org
+ads.pickmeup-ltd.com
+ads.planet.nl
+ads.pni.com
+ads.pof.com
+ads.powweb.com
+ads.primissima.it
+ads.printscr.com
+ads.prisacom.com
+ads.program3.com
+ads.psd2html.com
+ads.pushplay.com
+ads.quoka.de
+ads.rcs.it
+ads.recoletos.es
+ads.rediff.com
+ads.redlightcenter.com
+ads.redtube.com
+ads.resoom.de
+ads.returnpath.net
+ads.s3.sitepoint.com
+ads.satyamonline.com
+ads.savannahnow.com
+ads.saymedia.com
+ads.scifi.com
+ads.seniorfriendfinder.com
+ads.servebom.com
+ads.sexinyourcity.com
+ads.shizmoo.com
+ads.shopstyle.com
+ads.sift.co.uk
+ads.silverdisc.co.uk
+ads.slim.com
+ads.smartclick.com
+ads.soft32.com
+ads.space.com
+ads.sptimes.com
+ads.stackoverflow.com
+ads.sun.com
+ads.supplyframe.com
+ads.t-online.de
+ads.tahono.com
+ads.techtv.com
+ads.telegraph.co.uk
+ads.themovienation.com
+ads.thestar.com
+ads.tmcs.net
+ads.totallyfreestuff.com
+ads.townhall.com
+ads.trinitymirror.co.uk
+ads.tripod.com
+ads.tripod.lycos.co.uk
+ads.tripod.lycos.de
+ads.tripod.lycos.es
+ads.tripod.lycos.it
+ads.tripod.lycos.nl
+ads.tripod.spray.se
+ads.tso.dennisnet.co.uk
+ads.uknetguide.co.uk
+ads.ultimate-guitar.com
+ads.uncrate.com
+ads.undertone.com
+ads.usatoday.com
+ads.v3.com
+ads.verticalresponse.com
+ads.vgchartz.com
+ads.videosz.com
+ads.virtual-nights.com
+ads.virtualcountries.com
+ads.vnumedia.com
+ads.waps.cn
+ads.wapx.cn
+ads.weather.ca
+ads.web.aol.com
+ads.web.cs.com
+ads.web.de
+ads.webmasterpoint.org
+ads.websiteservices.com
+ads.whi.co.nz
+ads.whoishostingthis.com
+ads.wiezoekje.nl
+ads.wikia.nocookie.net
+ads.wineenthusiast.com
+ads.wwe.biz
+ads.xhamster.com
+ads.xtra.co.nz
+ads.y-0.net
+ads.yahoo.com
+ads.yimg.com
+ads.yldmgrimg.net
+ads.yourfreedvds.com
+ads.youtube.com
+ads.zdnet.com
+ads.ztod.com
+ads03.redtube.com
+ads1.canoe.ca
+ads1.mediacapital.pt
+ads1.msn.com
+ads1.rne.com
+ads1.virtual-nights.com
+ads10.speedbit.com
+ads180.com
+ads2.brazzers.com
+ads2.clearchannel.com
+ads2.contentabc.com
+ads2.gamecity.net
+ads2.jubii.dk
+ads2.net-communities.co.uk
+ads2.oneplace.com
+ads2.rne.com
+ads2.virtual-nights.com
+ads2.xnet.cz
+ads2004.treiberupdate.de
+ads3.contentabc.com
+ads3.gamecity.net
+ads3.virtual-nights.com
+ads4.clearchannel.com
+ads4.gamecity.net
+ads4.virtual-nights.com
+ads4homes.com
+ads5.canoe.ca
+ads5.virtual-nights.com
+ads6.gamecity.net
+ads7.gamecity.net
+ads8.com
+adsatt.abc.starwave.com
+Adsatt.ABCNews.starwave.com
+adsatt.espn.go.com
+adsatt.espn.starwave.com
+Adsatt.go.starwave.com
+adsby.bidtheatre.com
+adscale.de
+adscholar.com
+adscience.nl
+adscpm.com
+adsdaq.com
+adsdk.com
+adsend.de
+adserv.evo-x.de
+adserv.gamezone.de
+adserv.iafrica.com
+adserv.qconline.com
+adserve.ams.rhythmxchange.com
+adserver-live.yoc.mobi
+adserver.43plc.com
+adserver.71i.de
+adserver.adultfriendfinder.com
+adserver.aidameter.com
+adserver.aol.fr
+adserver.beggarspromo.com
+adserver.betandwin.de
+adserver.bing.com
+adserver.bizhat.com
+adserver.break-even.it
+adserver.cams.com
+adserver.com
+adserver.digitoday.com
+adserver.dotcommedia.de
+adserver.finditquick.com
+adserver.flossiemediagroup.com
+adserver.freecity.de
+adserver.freenet.de
+adserver.friendfinder.com
+adserver.hardsextube.com
+adserver.hardwareanalysis.com
+adserver.html.it
+adserver.irishwebmasterforum.com
+adserver.janes.com
+adserver.libero.it
+adserver.news.com.au
+adserver.ngz-network.de
+adserver.nydailynews.com
+adserver.o2.pl
+adserver.oddschecker.com
+adserver.omroepzeeland.nl
+adserver.pl
+adserver.portalofevil.com
+adserver.portugalmail.net
+adserver.portugalmail.pt
+adserver.sanomawsoy.fi
+adserver.sciflicks.com
+adserver.sharewareonline.com
+adserver.spankaway.com
+adserver.startnow.com
+adserver.theonering.net
+adserver.twitpic.com
+adserver.viagogo.com
+adserver.virginmedia.com
+adserver.yahoo.com
+adserver01.de
+adserver1-images.backbeatmedia.com
+adserver1.backbeatmedia.com
+adserver1.mindshare.de
+adserver1.ogilvy-interactive.de
+adserver2.mindshare.de
+adserverplus.com
+adserversolutions.com
+adservinginternational.com
+adsfac.eu
+adsfac.net
+adsfac.us
+adshost1.com
+adside.com
+adsk2.co
+adskape.ru
+adsklick.de
+adsmarket.com
+adsmart.co.uk
+adsmart.com
+adsmart.net
+adsmogo.com
+adsnative.com
+adsoftware.com
+adsoldier.com
+adsonar.com
+adspace.ro
+adspeed.net
+adspirit.de
+adsponse.de
+adsremote.scrippsnetworks.com
+adsrevenue.net
+adsrv.deviantart.com
+adsrv.eacdn.com
+adsrv.iol.co.za
+adsrvr.org
+adsstat.com
+adstat.4u.pl
+adstest.weather.com
+adsupply.com
+adsymptotic.com
+adsynergy.com
+adsys.townnews.com
+adsystem.simplemachines.org
+adtech.de
+adtechus.com
+adtegrity.net
+adthis.com
+adtiger.de
+adtoll.com
+adtology.com
+adtoma.com
+adtrace.org
+adtrade.net
+adtrading.de
+adtrak.net
+adtriplex.com
+adultadvertising.com
+adv-adserver.com
+adv-banner.libero.it
+adv.cooperhosting.net
+adv.freeonline.it
+adv.hwupgrade.it
+adv.livedoor.com
+adv.webmd.com
+adv.wp.pl
+adv.yo.cz
+advariant.com
+adventory.com
+advert.bayarea.com
+advert.dyna.ultraweb.hu
+adverticum.com
+adverticum.net
+adverticus.de
+advertise.com
+advertiseireland.com
+advertisespace.com
+advertising.com
+advertising.guildlaunch.net
+advertisingbanners.com
+advertisingbox.com
+advertisingtag.net
+advertmarket.com
+advertmedia.de
+advertpro.sitepoint.com
+advertpro.ya.com
+adverts.carltononline.com
+advertserve.com
+advertstream.com
+advertwizard.com
+advideo.uimserv.net
+adview.ppro.de
+advisormedia.cz
+adviva.net
+advnt.com
+adwareremovergold.com
+adwhirl.com
+adwitserver.com
+adworldnetwork.com
+adworx.at
+adworx.be
+adworx.nl
+adx.allstar.cz
+adx.atnext.com
+adxpansion.com
+adxpose.com
+adxvalue.com
+adyea.com
+adzerk.net
+adzerk.s3.amazonaws.com
+adzones.com
+af-ad.co.uk
+affbuzzads.com
+affili.net
+affiliate.1800flowers.com
+affiliate.doubleyourdating.com
+affiliate.dtiserv.com
+affiliate.gamestop.com
+affiliate.mercola.com
+affiliate.mogs.com
+affiliate.offgamers.com
+affiliate.travelnow.com
+affiliate.viator.com
+affiliatefuel.com
+affiliatefuture.com
+affiliates.allposters.com
+affiliates.babylon.com
+affiliates.digitalriver.com
+affiliates.globat.com
+affiliates.internationaljock.com
+affiliates.streamray.com
+affiliates.thinkhost.net
+affiliates.thrixxx.com
+affiliates.ultrahosting.com
+affiliatetracking.com
+affiliatetracking.net
+affiliatewindow.com
+affiliation-france.com
+afftracking.justanswer.com
+ah-ha.com
+ahalogy.com
+aidu-ads.de
+aim4media.com
+aistat.net
+aktrack.pubmatic.com
+alclick.com
+alenty.com
+alexa-sitestats.s3.amazonaws.com
+alipromo.com
+all4spy.com
+alladvantage.com
+allosponsor.com
+amazingcounters.com
+amazon-adsystem.com
+americash.com
+amung.us
+an.tacoda.net
+anahtars.com
+analytics.adpost.org
+analytics.google.com
+analytics.live.com
+analytics.yahoo.com
+anm.intelli-direct.com
+annonser.dagbladet.no
+api.intensifier.de
+apture.com
+arc1.msn.com
+arcadebanners.com
+ard.xxxblackbook.com
+are-ter.com
+as.webmd.com
+as1.advfn.com
+assets1.exgfnetwork.com
+assoc-amazon.com
+at-adserver.alltop.com
+atdmt.com
+athena-ads.wikia.com
+atwola.com
+auctionads.com
+auctionads.net
+audience2media.com
+audit.median.hu
+audit.webinform.hu
+auto-bannertausch.de
+autohits.dk
+avenuea.com
+avpa.javalobby.org
+avres.net
+avsads.com
+awempire.com
+awin1.com
+azfront.com
+b-1st.com
+b.aol.com
+b.engadget.com
+ba.afl.rakuten.co.jp
+babs.tv2.dk
+backbeatmedia.com
+banik.redigy.cz
+banner-exchange-24.de
+banner.ad.nu
+banner.ambercoastcasino.com
+banner.blogranking.net
+banner.buempliz-online.ch
+banner.casino.net
+banner.casinodelrio.com
+banner.cotedazurpalace.com
+banner.coza.com
+banner.cz
+banner.easyspace.com
+banner.elisa.net
+banner.eurogrand.com
+banner.featuredusers.com
+banner.getgo.de
+banner.goldenpalace.com
+banner.img.co.za
+banner.inyourpocket.com
+banner.kiev.ua
+banner.linux.se
+banner.media-system.de
+banner.mindshare.de
+banner.nixnet.cz
+banner.noblepoker.com
+banner.northsky.com
+banner.orb.net
+banner.penguin.cz
+banner.rbc.ru
+banner.relcom.ru
+banner.tanto.de
+banner.titan-dsl.de
+banner.vadian.net
+banner.webmersion.com
+banner.wirenode.com
+bannerads.de
+bannerboxes.com
+bannercommunity.de
+bannerconnect.com
+bannerconnect.net
+bannerexchange.cjb.net
+bannerflow.com
+bannergrabber.internet.gr
+bannerhost.com
+bannerimage.com
+bannerlandia.com.ar
+bannermall.com
+bannermarkt.nl
+bannerpower.com
+banners.adultfriendfinder.com
+banners.amigos.com
+banners.asiafriendfinder.com
+banners.audioholics.com
+banners.babylon-x.com
+banners.bol.com.br
+banners.cams.com
+banners.clubseventeen.com
+banners.czi.cz
+banners.dine.com
+banners.direction-x.com
+banners.directnic.com
+banners.easydns.com
+banners.freett.com
+banners.friendfinder.com
+banners.getiton.com
+banners.iq.pl
+banners.isoftmarketing.com
+banners.lifeserv.com
+banners.linkbuddies.com
+banners.passion.com
+banners.resultonline.com
+banners.sexsearch.com
+banners.sys-con.com
+banners.thomsonlocal.com
+banners.videosz.com
+banners.virtuagirlhd.com
+banners.wunderground.com
+bannerserver.com
+bannersgomlm.com
+bannershotlink.perfectgonzo.com
+bannersng.yell.com
+bannerspace.com
+bannerswap.com
+bannertesting.com
+bannery.cz
+bannieres.acces-contenu.com
+bans.adserver.co.il
+bans.bride.ru
+barnesandnoble.bfast.com
+basebanner.com
+baypops.com
+bbelements.com
+bbn.img.com.ua
+begun.ru
+belstat.com
+belstat.nl
+berp.com
+best-pr.info
+best-top.ro
+bestsearch.net
+bhclicks.com
+bidclix.com
+bidclix.net
+bidswitch.net
+bidtrk.com
+bidvertiser.com
+bigbangmedia.com
+bigclicks.com
+billboard.cz
+bitads.net
+bitmedianetwork.com
+bizad.nikkeibp.co.jp
+bizrate.com
+blast4traffic.com
+blingbucks.com
+blogads.com
+blogcounter.de
+blogherads.com
+blogrush.com
+blogtoplist.se
+blogtopsites.com
+blueadvertise.com
+bluekai.com
+bluelithium.com
+bluewhaleweb.com
+bm.annonce.cz
+bn.bfast.com
+boersego-ads.de
+boldchat.com
+boom.ro
+boomads.com
+boost-my-pr.de
+box.anchorfree.net
+bpath.com
+braincash.com
+brandreachsys.com
+bravenet.com.invalid
+bridgetrack.com
+brightinfo.com
+british-banners.com
+bs.yandex.ru
+bttrack.com
+budsinc.com
+bullseye.backbeatmedia.com
+buyhitscheap.com
+buysellads.com
+buzzonclick.com
+bvalphaserver.com
+bwp.download.com
+c.bigmir.net
+c1.nowlinux.com
+c1exchange.com
+campaign.bharatmatrimony.com
+caniamedia.com
+carbonads.com
+carbonads.net
+casalemedia.com
+casalmedia.com
+cash4members.com
+cash4popup.de
+cashcrate.com
+cashengines.com
+cashfiesta.com
+cashlayer.com
+cashpartner.com
+casinogames.com
+casinopays.com
+casinorewards.com
+casinotraffic.com
+casinotreasure.com
+cbanners.virtuagirlhd.com
+cbmall.com
+cdn.freefacti.com
+cdn.freefarcy.com
+cecash.com
+centerpointmedia.com
+ceskydomov.alias.ngs.modry.cz
+cetrk.com
+cgicounter.puretec.de
+ch.questionmarket.com
+chameleon.ad
+channelintelligence.com
+chart.dk
+chartbeat.com
+chartbeat.net
+checkm8.com
+checkstat.nl
+chestionar.ro
+chitika.net
+cibleclick.com.invalid
+cityads.telus.net
+cj.com
+cjbmanagement.com
+cjlog.com
+claria.com
+class-act-clicks.com
+click.absoluteagency.com
+click.fool.com
+click.kmindex.ru
+click2freemoney.com
+click2paid.com
+clickability.com
+clickadz.com
+clickagents.com
+clickbank.com
+clickbank.net
+clickbooth.com
+clickboothlnk.com
+clickbrokers.com
+clickcompare.co.uk
+clickdensity.com
+clickedyclick.com
+clickhereforcellphones.com
+clickhouse.com
+clickhype.com
+clicklink.jp
+clickmedia.ro
+clickonometrics.pl
+clicks.equantum.com
+clicks.mods.de
+clickserve.cc-dt.com
+clicksor.com
+clicktag.de
+clickthruserver.com
+clickthrutraffic.com
+clicktrace.info
+clicktrack.ziyu.net
+clicktracks.com
+clicktrade.com
+clickxchange.com
+clickz.com
+clickzxc.com
+clicmanager.fr
+clientmetrics-pa.googleapis.com
+clients.tbo.com
+clixgalore.com
+clk.konflab.com
+clkads.com
+clkrev.com
+cluster.adultworld.com
+clustrmaps.com
+cmpstar.com
+cnomy.com
+cnt.spbland.ru
+cnt1.pocitadlo.cz
+code-server.biz
+colonize.com
+comclick.com
+commindo-media-ressourcen.de
+commissionmonster.com
+compactbanner.com
+comprabanner.it
+confirmed-profits.com
+connextra.com
+contaxe.de
+content.acc-hd.de
+content.ad
+contextweb.com
+conversantmedia.com
+conversionruler.com
+cookies.cmpnet.com
+coremetrics.com
+count.rbc.ru
+count.rin.ru
+count.west263.com
+counted.com
+counter.bloke.com
+counter.cnw.cz
+counter.cz
+counter.dreamhost.com
+counter.fateback.com
+counter.mirohost.net
+counter.mojgorod.ru
+counter.nowlinux.com
+counter.rambler.ru
+counter.search.bg
+counter.sparklit.com
+counter.yadro.ru
+counters.honesty.com
+counting.kmindex.ru
+counts.tucows.com
+coupling-media.de
+cpalead.com
+cpays.com
+cpmaffiliation.com
+cpmstar.com
+cpxinteractive.com
+cqcounter.com
+crakmedia.com
+craktraffic.com
+crawlability.com
+crazypopups.com
+creafi-online-media.com
+creative.whi.co.nz
+creatives.as4x.tmcs.net
+creatives.livejasmin.com
+crispads.com
+criteo.com
+crowdgravity.com
+crtv.mate1.com
+crwdcntrl.net
+ctnetwork.hu
+cubics.com
+customad.cnn.com
+cyberbounty.com
+cybermonitor.com
+d.adroll.com
+dakic-ia-300.com
+danban.com
+dapper.net
+datashreddergold.com
+dbbsrv.com
+dc-storm.com
+de17a.com
+dealdotcom.com
+debtbusterloans.com
+decknetwork.net
+deloo.de
+demandbase.com
+demdex.net
+di1.shopping.com
+dialerporn.com
+didtheyreadit.com
+direct-xxx-access.com
+directaclick.com
+directivepub.com
+directleads.com
+directorym.com
+directtrack.com
+discountclick.com
+displayadsmedia.com
+dist.belnk.com
+dmtracker.com
+dmtracking.alibaba.com
+dmtracking2.alibaba.com
+dnads.directnic.com
+domaining.in
+domainsponsor.com
+domainsteam.de
+domdex.com
+doubleclick.com
+doubleclick.de
+doubleclick.net
+doublepimp.com
+drumcash.com
+dynamic.fmpub.net
+e-adimages.scrippsnetworks.com
+e-bannerx.com
+e-debtconsolidation.com
+e-m.fr
+e-n-t-e-r-n-e-x.com
+e-planning.net
+e.kde.cz
+eadexchange.com
+eas.almamedia.fi
+easyhits4u.com
+ebayadvertising.com
+ebocornac.com
+ebuzzing.com
+ecircle-ag.com
+eclick.vn
+ecoupons.com
+edgeio.com
+effectivemeasure.com
+effectivemeasure.net
+eiv.baidu.com
+elitedollars.com
+elitetoplist.com
+emarketer.com
+emediate.dk
+emediate.eu
+engine.espace.netavenir.com
+enginenetwork.com
+enoratraffic.com
+enquisite.com
+entercasino.com
+entrecard.s3.amazonaws.com
+eqads.com
+ero-advertising.com
+esellerate.net
+estat.com
+etahub.com
+etargetnet.com
+etracker.de
+eu-adcenter.net
+eu1.madsone.com
+eur.a1.yimg.com
+eurekster.com
+euroclick.com
+euros4click.de
+eusta.de
+evergage.com
+evidencecleanergold.com
+ewebcounter.com
+exchange-it.com
+exchange.bg
+exchangead.com
+exchangeclicksonline.com
+exelator.com
+exit76.com
+exitexchange.com
+exitfuel.com
+exoclick.com
+exogripper.com
+experteerads.com
+exponential.com
+express-submit.de
+extractorandburner.com
+extreme-dm.com
+extremetracking.com
+eyeblaster.com
+eyereturn.com
+eyeviewads.com
+eyewonder.com
+ezula.com
+f5biz.com
+fast-adv.it
+fastclick.com
+fastclick.com.edgesuite.net
+fastclick.net
+fb-promotions.com
+fc.webmasterpro.de
+feedbackresearch.com
+feedjit.com
+ffxcam.fairfax.com.au
+fimc.net
+fimserve.com
+findcommerce.com
+findyourcasino.com
+fineclicks.com
+first.nova.cz
+firstlightera.com
+flashtalking.com
+fleshlightcash.com
+flexbanner.com
+flowgo.com
+flurry.com
+fonecta.leiki.com
+foo.cosmocode.de
+forex-affiliate.net
+fpctraffic.com
+fpctraffic2.com
+fragmentserv.iac-online.de
+free-banners.com
+freebanner.com
+freelogs.com
+freeonlineusers.com
+freepay.com
+freestats.com
+freestats.tv
+freewebcounter.com
+funklicks.com
+funpageexchange.com
+fusionads.net
+fusionquest.com
+fxstyle.net
+galaxien.com
+game-advertising-online.com
+gamehouse.com
+gamesites100.net
+gamesites200.com
+gamesitestop100.com
+gator.com
+gbanners.hornymatches.com
+gemius.pl
+geo.digitalpoint.com
+geobanner.adultfriendfinder.com
+geovisite.com
+getclicky.com
+globalismedia.com
+globaltakeoff.net
+globaltrack.com.invalid
+globe7.com
+globus-inter.com
+gmads.net
+go-rank.de
+goingplatinum.com
+goldstats.com
+google-analytics.com
+googleadservices.com
+googlesyndication.com
+gostats.com
+gp.dejanews.com
+gpr.hu
+grafstat.ro
+grapeshot.co.uk
+greystripe.com
+gtop100.com
+gunggo.com
+harrenmedia.com
+harrenmedianetwork.com
+havamedia.net
+heias.com
+hentaicounter.com
+herbalaffiliateprogram.com
+hexusads.fluent.ltd.uk
+heyos.com
+hgads.com
+hidden.gogoceleb.com
+hightrafficads.com
+histats.com
+hit-parade.com
+hit.bg
+hit.ua
+hit.webcentre.lycos.co.uk
+hitbox.com
+hitcents.com
+hitfarm.com
+hitiz.com
+hitlist.ru
+hitlounge.com
+hitometer.com
+hits.europuls.eu
+hits.informer.com
+hits.puls.lv
+hits.theguardian.com
+hits4me.com
+hits4pay.com
+hitslink.com
+hittail.com
+hollandbusinessadvertising.nl
+homepageking.de
+hostedads.realitykings.com
+hotjar.com
+hotkeys.com
+hotlog.ru
+hotrank.com.tw
+hs-analytics.net
+htmlhubing.xyz
+httpool.com
+hurricanedigitalmedia.com
+hydramedia.com
+hyperbanner.net
+hypertracker.com
+i-clicks.net
+i.xx.openx.com
+i1img.com
+i1media.no
+ia.iinfo.cz
+iad.anm.co.uk
+iadnet.com
+iasds01.com
+iconadserver.com
+icptrack.com
+idcounter.com
+identads.com
+idregie.com
+idtargeting.com
+ientrymail.com
+iesnare.com
+ifa.tube8live.com
+ilbanner.com
+ilead.itrack.it
+ilovecheating.com
+imageads.canoe.ca
+imagecash.net
+images-pw.secureserver.net
+images.v3.com
+imarketservices.com
+img.prohardver.hu
+imgpromo.easyrencontre.com
+imonitor.nethost.cz
+imprese.cz
+impressionmedia.cz
+impressionz.co.uk
+imrworldwide.com
+inboxdollars.com
+incentaclick.com
+indexstats.com
+indieclick.com
+industrybrains.com
+inetlog.ru
+infinite-ads.com
+infinityads.com
+infolinks.com
+information.com
+inringtone.com
+insightexpress.com
+insightexpressai.com
+instantmadness.com
+intelliads.com
+intellitxt.com
+interactive.forthnet.gr
+intergi.com
+internetfuel.com
+interreklame.de
+interstat.hu
+ip.ro
+ip193.cn
+iperceptions.com
+ipro.com
+ireklama.cz
+itfarm.com
+itop.cz
+its-that-easy.com
+itsptp.com
+jcount.com
+jinkads.de
+joetec.net
+js.users.51.la
+juicyads.com
+jumptap.com
+justrelevant.com
+justwebads.com
+k.iinfo.cz
+kanoodle.com
+keymedia.hu
+kindads.com
+kissmetrics.com
+kliks.nl
+kniverto.com
+komoona.com
+kompasads.com
+kontera.com
+kt-g.de
+ktu.sv2.biz
+lakequincy.com
+launchbit.com
+layer-ad.de
+layer-ads.de
+lbn.ru
+lct.salesforce.com
+lead-analytics.nl
+leadboltads.net
+leadclick.com
+leadingedgecash.com
+leadzupc.com
+levelrate.de
+lfstmedia.com
+liftdna.com
+ligatus.com
+ligatus.de
+lightningcast.net
+lightspeedcash.com
+link-booster.de
+link4ads.com
+linkadd.de
+linkbuddies.com
+linkexchange.com
+linkprice.com
+linkrain.com
+linkreferral.com
+links-ranking.de
+linkshighway.com
+linkstorms.com
+linkswaper.com
+linktarget.com
+liquidad.narrowcastmedia.com
+liveintent.com
+liverail.com
+loading321.com
+log.btopenworld.com
+logua.com
+lop.com
+lucidmedia.com
+lzjl.com
+m.webtrends.com
+m1.webstats4u.com
+m4n.nl
+mackeeperapp.mackeeper.com
+madclient.uimserv.net
+madisonavenue.com
+mads.cnet.com
+madvertise.de
+marchex.com
+market-buster.com
+marketing.888.com
+marketing.hearstmagazines.nl
+marketing.nyi.net
+marketing.osijek031.com
+marketingsolutions.yahoo.com
+maroonspider.com
+mas.sector.sk
+mastermind.com
+matchcraft.com
+mathtag.com
+max.i12.de
+maximumcash.com
+mbn.com.ua
+mbs.megaroticlive.com
+mbuyu.nl
+mdotm.com
+measuremap.com
+media-adrunner.mycomputer.com
+media-servers.net
+media.ftv-publicite.fr
+media.funpic.de
+media6degrees.com
+mediaarea.eu
+mediacharger.com
+mediadvertising.ro
+mediageneral.com
+mediamath.com
+mediamgr.ugo.com
+mediaplazza.com
+mediaplex.com
+mediascale.de
+mediatext.com
+mediax.angloinfo.com
+mediaz.angloinfo.com
+medleyads.com
+medyanetads.com
+megacash.de
+megago.com
+megastats.com
+megawerbung.de
+metaffiliation.com
+metanetwork.com
+methodcash.com
+metrics.cnn.com
+metrics.windowsitpro.com
+mgid.com
+miarroba.com
+microstatic.pl
+microticker.com
+midnightclicking.com
+misstrends.com
+mixpanel.com
+mixtraffic.com
+mjxads.internet.com
+mlm.de
+mmismm.com
+mmtro.com
+moatads.com
+mobclix.com
+mocean.mobi
+moneyexpert.com
+monsterpops.com
+mopub.com
+mouseflow.com
+mpstat.us
+mr-rank.de
+mrskincash.com
+mtree.com
+musiccounter.ru
+muwmedia.com
+myaffiliateprogram.com
+mybloglog.com
+mycounter.ua
+mymoneymakingapp.com
+mypagerank.net
+mypagerank.ru
+mypowermall.com
+mystat-in.net
+mystat.pl
+mytop-in.net
+n69.com
+naiadsystems.com.invalid
+naj.sk
+namimedia.com
+nastydollars.com
+navigator.io
+navrcholu.cz
+nbjmp.com
+ndparking.com
+nedstat.com
+nedstat.nl
+nedstatbasic.net
+nedstatpro.net
+nend.net
+neocounter.neoworx-blog-tools.net
+neoffic.com
+net-filter.com
+netaffiliation.com
+netagent.cz
+netclickstats.com
+netcommunities.com
+netdirect.nl
+netincap.com
+netpool.netbookia.net
+netshelter.net
+neudesicmediagroup.com
+newads.bangbros.com
+newbie.com
+newnet.qsrch.com
+newnudecash.com
+newopenx.detik.com
+newt1.adultadworld.com
+newt1.adultworld.com
+newtopsites.com
+ng3.ads.warnerbros.com
+ngs.impress.co.jp
+nitroclicks.com
+novem.pl
+nuggad.net
+numax.nu-1.com
+nuseek.com
+oas.benchmark.fr
+oas.foxnews.com
+oas.repubblica.it
+oas.roanoke.com
+oas.salon.com
+oas.toronto.com
+oas.uniontrib.com
+oas.villagevoice.com
+oascentral.businessweek.com
+oascentral.chicagobusiness.com
+oascentral.fortunecity.com
+oascentral.register.com
+oewa.at
+oewabox.at
+offerforge.com
+offermatica.com
+olivebrandresponse.com
+omniture.com
+onclasrv.com
+onclickads.net
+oneandonlynetwork.com
+onenetworkdirect.com
+onestat.com
+onestatfree.com
+online-metrix.net
+onlinecash.com
+onlinecashmethod.com
+onlinerewardcenter.com
+openad.tf1.fr
+openad.travelnow.com
+openads.friendfinder.com
+openads.org
+openx.angelsgroup.org.uk
+openx.blindferret.com
+opienetwork.com
+optimost.com
+optmd.com
+ordingly.com
+ota.cartrawler.com
+otto-images.developershed.com
+outbrain.com
+overture.com
+owebmoney.ru
+oxado.com
+oxcash.com
+oxen.hillcountrytexas.com
+p.adpdx.com
+pagead.l.google.com
+pagefair.com
+pagerank-ranking.de
+pagerank-submitter.de
+pagerank-united.de
+pagerank4you.com
+pageranktop.com
+parse.ly.invalid
+parsely.com
+partage-facile.com
+partner-ads.com
+partner.pelikan.cz
+partner.topcities.com
+partnerad.l.google.com
+partnercash.de
+partners.priceline.com
+passion-4.net
+pay-ads.com
+paycounter.com
+paypopup.com
+payserve.com
+pbnet.ru
+pcash.imlive.com
+peep-auktion.de
+peer39.com
+pennyweb.com
+pepperjamnetwork.com
+percentmobile.com
+perfectaudience.com
+perfiliate.com
+performancerevenue.com
+performancerevenues.com
+performancing.com
+pgmediaserve.com
+pgpartner.com
+pheedo.com
+phoenix-adrunner.mycomputer.com
+phpadsnew.new.natuurpark.nl
+phpmyvisites.net
+picadmedia.com
+pillscash.com
+pimproll.com
+pixel.adsafeprotected.com
+pixel.jumptap.com
+pixel.redditmedia.com
+play4traffic.com
+playhaven.com
+plista.com
+plugrush.com
+pointroll.com
+pop-under.ru
+popads.net
+popub.com
+popunder.ru
+popup.msn.com
+popupmoney.com
+popupnation.com
+popups.infostart.com
+popuptraffic.com
+porngraph.com
+porntrack.com
+postrelease.com
+potenza.cz
+pr-ten.de
+praddpro.de
+prchecker.info
+precisioncounter.com
+predictad.com
+primaryads.com
+primetime.net
+privatecash.com
+pro-advertising.com
+pro.i-doctor.co.kr
+proext.com
+profero.com
+projectwonderful.com
+promo.badoink.com
+promo.ulust.com
+promo1.webcams.nl
+promobenef.com
+promos.fling.com
+promote.pair.com
+promotion-campaigns.com
+pronetadvertising.com
+propellerads.com
+proranktracker.com
+proton-tm.com
+protraffic.com
+provexia.com
+prsitecheck.com
+psstt.com
+pub.chez.com
+pub.club-internet.fr
+pub.hardware.fr
+pub.realmedia.fr
+pubdirecte.com
+publicidad.elmundo.es
+pubmatic.com
+pubs.lemonde.fr
+pulse360.com
+q.azcentral.com
+qctop.com
+qnsr.com
+quantcast.com
+quantserve.com
+quarterserver.de
+questaffiliates.net
+quigo.com
+quinst.com
+quisma.com
+rad.msn.com
+radar.cedexis.com
+radarurl.com
+radiate.com
+rampidads.com
+rank-master.com
+rank-master.de
+rankchamp.de
+ranking-charts.de
+ranking-hits.de
+ranking-id.de
+ranking-links.de
+ranking-liste.de
+ranking-street.de
+rankingchart.de
+rankingscout.com
+rankyou.com
+rapidcounter.com
+rate.ru
+ratings.lycos.com
+rb1.design.ru
+re-directme.com
+reachjunction.com
+reactx.com
+readserver.net
+realcastmedia.com
+realclix.com
+realmedia-a800.d4p.net
+realtechnetwork.com
+realtracker.com
+reduxmedia.com
+reedbusiness.com.invalid
+referralware.com
+regnow.com
+reinvigorate.net
+reklam.rfsl.se
+reklama.mironet.cz
+reklama.reflektor.cz
+reklamcsere.hu
+reklame.unwired-i.net
+reklamer.com.ua
+relevanz10.de
+relmaxtop.com
+remotead.cnet.com
+republika.onet.pl
+retargeter.com
+revenue.net
+revenuedirect.com
+revsci.net
+revstats.com
+richmails.com
+richmedia.yimg.com
+richwebmaster.com
+rightstats.com
+rlcdn.com
+rle.ru
+rmads.msn.com
+rmedia.boston.com
+roar.com
+robotreplay.com
+roia.biz
+rok.com.com
+rose.ixbt.com
+rotabanner.com
+roxr.net
+rtbpop.com
+rtbpopd.com
+ru-traffic.com
+ru4.com
+rubiconproject.com
+s.adroll.com
+s2d6.com
+sageanalyst.net
+sail-horizon.com
+samsungacr.com
+samsungads.com
+sbx.pagesjaunes.fr
+scambiobanner.aruba.it
+scanscout.com
+scopelight.com
+scorecardresearch.com
+scratch2cash.com
+scripte-monster.de
+searchfeast.com
+searchmarketing.com
+searchramp.com
+secure.webconnect.net
+sedoparking.com
+sedotracker.com
+seeq.com.invalid
+sensismediasmart.com.au
+seo4india.com
+serv0.com
+servedby-buysellads.com
+servedbyadbutler.com
+servedbyopenx.com
+servethis.com
+services.hearstmags.com
+serving-sys.com
+sexaddpro.de
+sexadvertentiesite.nl
+sexcounter.com
+sexinyourcity.com
+sexlist.com
+sextracker.com
+sexystat.com
+shareadspace.com
+shareasale.com
+sharepointads.com
+sher.index.hu
+shinystat.com
+shinystat.it
+shoppingads.com
+siccash.com
+sidebar.angelfire.com
+sinoa.com
+sitemeter.com
+sitestat.com
+sixsigmatraffic.com
+skimresources.com
+skylink.vn
+slickaffiliate.com
+slopeaota.com
+smart4ads.com
+smartadserver.com
+smowtion.com
+snapads.com
+snoobi.com
+socialspark.com
+softclick.com.br
+spacash.com
+sparkstudios.com
+specificmedia.co.uk
+specificpop.com
+spezialreporte.de
+spinbox.techtracker.com
+spinbox.versiontracker.com
+sponsorads.de
+sponsorpro.de
+sponsors.thoughtsmedia.com
+spot.fitness.com
+spotxchange.com
+spylog.com
+spywarelabs.com
+spywarenuker.com
+spywords.com
+srwww1.com
+starffa.com
+start.freeze.com
+stat.cliche.se
+stat.dealtime.com
+stat.dyna.ultraweb.hu
+stat.pl
+stat.webmedia.pl
+stat.zenon.net
+stat24.com
+stat24.meta.ua
+statcounter.com
+static.fmpub.net
+static.itrack.it
+staticads.btopenworld.com
+statistik-gallup.net
+statm.the-adult-company.com
+stats.blogger.com
+stats.cts-bv.nl
+stats.directnic.com
+stats.hyperinzerce.cz
+stats.mirrorfootball.co.uk
+stats.multiup.org
+stats.olark.com
+stats.self.com
+stats.townnews.com
+stats.unwired-i.net
+stats.wordpress.com
+stats.x14.eu
+stats2.self.com
+stats4all.com
+statsie.com
+statxpress.com
+steelhouse.com
+steelhousemedia.com
+stickyadstv.com
+suavalds.com
+subscribe.hearstmags.com
+sugoicounter.com
+sumo.com
+sumome.com
+superclix.de
+superstats.com
+supertop.ru
+supertop100.com
+suptullog.com
+surfmusik-adserver.de
+swan-swan-goose.com
+swissadsolutions.com
+swordfishdc.com
+sx.trhnt.com
+t.insigit.com
+t.pusk.ru
+taboola.com
+tacoda.net
+tagular.com
+tailsweep.co.uk
+tailsweep.com
+tailsweep.se
+takru.com
+tangerinenet.biz
+tapad.com
+targad.de
+targetingnow.com
+targetnet.com
+targetpoint.com
+tatsumi-sys.jp
+tcads.net
+teads.tv
+techclicks.net
+teenrevenue.com
+teliad.de
+text-link-ads.com
+textad.sexsearch.com
+textads.biz
+textads.opera.com
+textlinks.com
+tfag.de
+theadhost.com
+theads.me
+thebugs.ws
+thecounter.com
+therapistla.com
+therichkids.com
+thrnt.com
+thruport.com
+tinybar.com
+tizers.net
+tlvmedia.com
+tntclix.co.uk
+top-casting-termine.de
+top-site-list.com
+top.list.ru
+top.mail.ru
+top.proext.com
+top100-images.rambler.ru
+top100.mafia.ru
+top123.ro
+top20.com.invalid
+top20free.com
+top90.ro
+topbarh.box.sk
+topbucks.com
+topforall.com
+topgamesites.net
+toplist.cz
+toplist.pornhost.com
+toplista.mw.hu
+toplistcity.com
+topmmorpgsites.com.invalid
+topping.com.ua
+toprebates.com
+topsafelist.net
+topsearcher.com
+topsir.com
+topsite.lv
+topsites.com.br
+topstats.com
+totemcash.com
+touchclarity.com
+touchclarity.natwest.com
+tour.brazzers.com
+tpnads.com
+track.adform.net
+track.anchorfree.com
+track.gawker.com
+trackalyzer.com
+tracker.icerocket.com
+tracker.marinsm.com
+tracking.crunchiemedia.com
+tracking.gajmp.com
+tracking.internetstores.de
+tracking.yourfilehost.com
+tracking101.com
+trackingsoft.com
+trackmysales.com
+tradeadexchange.com
+tradedoubler.com
+traffic-exchange.com
+traffic.liveuniversenetwork.com
+trafficadept.com
+trafficbalancerouting.com
+trafficcdn.liveuniversenetwork.com
+trafficfactory.biz
+trafficholder.com
+traffichunt.com
+trafficjunky.net
+trafficleader.com
+trafficsecrets.com
+trafficspaces.net
+trafficstrategies.com
+trafficswarm.com
+traffictrader.net
+trafficz.com
+trafficz.net
+traffiq.com
+trafic.ro
+travis.bosscasinos.com
+trekblue.com
+trekdata.com
+trendcounter.com
+trendmd.com
+trhunt.com
+tribalfusion.com
+trix.net
+truehits.net
+truehits1.gits.net.th
+truehits2.gits.net.th
+tsms-ad.tsms.com
+tubemogul.com
+turn.com
+tvmtracker.com
+twittad.com
+tyroo.com
+uarating.com
+ukbanners.com
+ultramercial.com
+unanimis.co.uk
+untd.com
+updated.com
+urlcash.net
+us.a1.yimg.com
+usapromotravel.com
+usmsad.tom.com
+utarget.co.uk
+utils.mediageneral.net
+v1.cnzz.com
+validclick.com
+valuead.com
+valueclick.com
+valueclickmedia.com
+valuecommerce.com
+valuesponsor.com
+veille-referencement.com
+ventivmedia.com
+vericlick.com
+vertadnet.com
+veruta.com
+vervewireless.com
+vibrantmedia.com
+video-stats.video.google.com
+videoegg.com
+view4cash.de
+viewpoint.com
+visistat.com
+visit.webhosting.yahoo.com
+visitbox.de
+visual-pagerank.fr
+visualrevenue.com
+voicefive.com
+vpon.com
+vrs.cz
+vs.tucows.com
+vungle.com
+warlog.ru
+wdads.sx.atl.publicus.com
+web-stat.com
+web.informer.com
+web2.deja.com
+webads.co.nz
+webads.nl
+webangel.ru
+webcash.nl
+webcounter.cz
+webcounter.goweb.de
+webgains.com
+webmaster-partnerprogramme24.de
+webmasterplan.com
+webmasterplan.de
+weborama.fr
+webpower.com
+webreseau.com
+webseoanalytics.com
+websponsors.com
+webstat.channel4.com
+webstat.com
+webstat.net
+webstats4u.com
+webtrackerplus.com
+webtraffic.se
+webtraxx.de
+webtrendslive.com
+werbung.meteoxpress.com
+wetrack.it
+whaleads.com
+whenu.com
+whispa.com
+whoisonline.net
+wholesaletraffic.info
+widespace.com
+widgetbucks.com
+wikia-ads.wikia.com
+window.nixnet.cz
+wintricksbanner.googlepages.com
+witch-counter.de
+wlmarketing.com
+wmirk.ru
+wonderlandads.com
+wondoads.de
+woopra.com
+worldwide-cash.net
+wtlive.com
+www-banner.chat.ru
+www-google-analytics.l.google.com
+www.banner-link.com.br
+www.dnps.com
+www.kaplanindex.com
+www.money4exit.de
+www.photo-ads.co.uk
+www1.gto-media.com
+www8.glam.com
+wwwpromoter.com
+x-traceur.com
+x6.yakiuchi.com
+xchange.ro
+xclicks.net
+xertive.com
+xg4ken.com
+xiti.com
+xplusone.com
+xponsor.com
+xq1.net
+xrea.com
+xtendmedia.com
+xtremetop100.com
+xxxcounter.com
+xxxmyself.com
+y.ibsys.com
+yab-adimages.s3.amazonaws.com
+yabuka.com
+yadro.ru
+yesads.com
+yesadvertising.com
+yieldads.com
+yieldlab.net
+yieldmanager.com
+yieldmanager.net
+yieldmo.com
+yieldtraffic.com
+yoc.mobi
+yoggrt.com
+z5x.net
+zangocash.com
+zanox-affiliate.de
+zanox.com
+zantracker.com
+zedo.com
+zencudo.co.uk
+zenkreka.com
+zenzuu.com
+zeus.developershed.com
+zeusclicks.com
+zintext.com
+zmedia.com
+zv1.november-lax.com
\ No newline at end of file
diff --git a/app/src/main/assets/js/click_a.js b/app/src/main/assets/js/click_a.js
index 81b12fd75c8..9f4ddc38450 100644
--- a/app/src/main/assets/js/click_a.js
+++ b/app/src/main/assets/js/click_a.js
@@ -22,7 +22,7 @@ if (!window.hasOwnProperty('frost_click_a')) {
if (!prevented) {
console.log('Click Intercept', url);
- Frost.loadUrl(url);
+ if (typeof Frost !== 'undefined') Frost.loadUrl(url);
}
e.stopPropagation();
e.preventDefault();
diff --git a/app/src/main/assets/js/click_a.min.js b/app/src/main/assets/js/click_a.min.js
index 059c1183a15..c7870e2fbff 100644
--- a/app/src/main/assets/js/click_a.min.js
+++ b/app/src/main/assets/js/click_a.min.js
@@ -8,8 +8,8 @@ var t=e.target||e.srcElement
var n=t.getAttribute("href")
;if(n.includes("photoset_token"))return
;prevented||(console.log("Click Intercept",n),
-Frost.loadUrl(n)),e.stopPropagation(),
-e.preventDefault()
+"undefined"!=typeof Frost&&Frost.loadUrl(n)),
+e.stopPropagation(),e.preventDefault()
}
},_frostPreventClick=function(){
console.log("Click prevented"),prevented=!0
diff --git a/app/src/main/assets/js/context_a.js b/app/src/main/assets/js/context_a.js
index 395dfca1234..c760176404c 100644
--- a/app/src/main/assets/js/context_a.js
+++ b/app/src/main/assets/js/context_a.js
@@ -9,7 +9,7 @@ if (!window.hasOwnProperty('frost_context_a')) {
var longClick = false;
var _frostAContext = function(e) {
- Frost.longClick(true);
+ if (typeof Frost !== 'undefined') Frost.longClick(true);
longClick = true;
/*
@@ -23,13 +23,19 @@ if (!window.hasOwnProperty('frost_context_a')) {
if (element.tagName === 'A' && element.getAttribute('href') !== '#') {
var url = element.getAttribute('href');
if (!url) return;
- if (url.includes('photoset_token')) return;
-
var text = element.parentNode.innerText;
- // console.log('Context Intercept', element.tagName, element.id, element.className)
- console.log('Context Content', url, text);
- Frost.contextMenu(url, text);
+ //check if image item exists
+ var image = element.parentNode.querySelector('[style*="background-image: url("]');
+ if (image) {
+ var imageUrl = window.getComputedStyle(image, null).backgroundImage.slice(5, -2);
+ console.log('Context image', imageUrl);
+ if (typeof Frost !== 'undefined') Frost.loadImage(imageUrl, text);
+ } else {
+ if (url.includes('photoset_token')) return;
+ console.log('Context Content', url, text);
+ if (typeof Frost !== 'undefined') Frost.contextMenu(url, text);
+ }
e.stopPropagation();
e.preventDefault();
}
@@ -39,7 +45,7 @@ if (!window.hasOwnProperty('frost_context_a')) {
document.addEventListener('touchend', function _frostEnd(e) {
if (longClick) {
- Frost.longClick(false);
+ if (typeof Frost !== 'undefined') Frost.longClick(false);
longClick = false;
}
}, true);
diff --git a/app/src/main/assets/js/context_a.min.js b/app/src/main/assets/js/context_a.min.js
index 82f89e8b6f9..5c5f033af0d 100644
--- a/app/src/main/assets/js/context_a.min.js
+++ b/app/src/main/assets/js/context_a.min.js
@@ -1,20 +1,28 @@
if(!window.hasOwnProperty("frost_context_a")){
console.log("frost_context_a frost_click_a"),
window.frost_context_a=!0
-;var longClick=!1,_frostAContext=function(t){
-Frost.longClick(!0),longClick=!0
-;var e=t.target||t.currentTarget||t.srcElement
-;if(e&&("A"!==e.tagName&&(e=e.parentNode),
-"A"!==e.tagName&&(e=e.parentNode),"A"===e.tagName&&"#"!==e.getAttribute("href"))){
-var o=e.getAttribute("href")
-;if(o.includes("photoset_token"))return
-;var n=e.parentNode.innerText
-;console.log("Context Content",o,n),Frost.contextMenu(o,n),
-t.stopPropagation(),t.preventDefault()
+;var longClick=!1,_frostAContext=function(e){
+"undefined"!=typeof Frost&&Frost.longClick(!0),
+longClick=!0
+;var t=e.target||e.currentTarget||e.srcElement
+;if(t&&("A"!==t.tagName&&(t=t.parentNode),
+"A"!==t.tagName&&(t=t.parentNode),"A"===t.tagName&&"#"!==t.getAttribute("href"))){
+var o=t.getAttribute("href")
+;if(!o)return
+;var n=t.parentNode.innerText,r=t.parentNode.querySelector('[style*="background-image: url("]')
+;if(r){
+var a=window.getComputedStyle(r,null).backgroundImage.slice(5,-2)
+;console.log("Context image",a),
+"undefined"!=typeof Frost&&Frost.loadImage(a,n)
+}else{
+if(o.includes("photoset_token"))return
+;console.log("Context Content",o,n),"undefined"!=typeof Frost&&Frost.contextMenu(o,n)
}
+e.stopPropagation(),e.preventDefault()
}
-;document.addEventListener("contextmenu",_frostAContext,!0),document.addEventListener("touchend",function(t){
-longClick&&(Frost.longClick(!1),
+}
+;document.addEventListener("contextmenu",_frostAContext,!0),document.addEventListener("touchend",function(e){
+longClick&&("undefined"!=typeof Frost&&Frost.longClick(!1),
longClick=!1)
},!0)
}
\ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt b/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt
index 4b62d24477f..3f5bdedac45 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt
@@ -10,6 +10,7 @@ import com.crashlytics.android.Crashlytics
import com.crashlytics.android.answers.Answers
import com.mikepenz.materialdrawer.util.AbstractDrawerImageLoader
import com.mikepenz.materialdrawer.util.DrawerImageLoader
+import com.pitchedapps.frost.BuildConfig
import com.pitchedapps.frost.facebook.FbCookie
import com.pitchedapps.frost.utils.CrashReportingTree
import com.pitchedapps.frost.utils.GlideApp
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt
index 122c571ef41..12cb955d67c 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt
@@ -2,6 +2,9 @@ package com.pitchedapps.frost
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
+import com.pitchedapps.frost.activities.LoginActivity
+import com.pitchedapps.frost.activities.MainActivity
+import com.pitchedapps.frost.activities.SelectorActivity
import com.pitchedapps.frost.dbflow.loadFbCookiesAsync
import com.pitchedapps.frost.facebook.FbCookie
import com.pitchedapps.frost.utils.L
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/AboutActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/AboutActivity.kt
similarity index 98%
rename from app/src/main/kotlin/com/pitchedapps/frost/AboutActivity.kt
rename to app/src/main/kotlin/com/pitchedapps/frost/activities/AboutActivity.kt
index 6cab2a59c8d..63ad8baed52 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/AboutActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/AboutActivity.kt
@@ -1,4 +1,4 @@
-package com.pitchedapps.frost
+package com.pitchedapps.frost.activities
import android.support.constraint.ConstraintLayout
import android.support.constraint.ConstraintSet
@@ -20,6 +20,8 @@ import com.mikepenz.fastadapter.IItem
import com.mikepenz.fastadapter.items.AbstractItem
import com.mikepenz.google_material_typeface_library.GoogleMaterial
import com.mikepenz.iconics.typeface.IIcon
+import com.pitchedapps.frost.BuildConfig
+import com.pitchedapps.frost.R
import com.pitchedapps.frost.utils.Prefs
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/BaseActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseActivity.kt
similarity index 93%
rename from app/src/main/kotlin/com/pitchedapps/frost/BaseActivity.kt
rename to app/src/main/kotlin/com/pitchedapps/frost/activities/BaseActivity.kt
index c2551125413..fd020af116a 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/BaseActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseActivity.kt
@@ -1,7 +1,8 @@
-package com.pitchedapps.frost
+package com.pitchedapps.frost.activities
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
+import com.pitchedapps.frost.R
import com.pitchedapps.frost.utils.Prefs
import com.pitchedapps.frost.utils.materialDialogThemed
import com.pitchedapps.frost.utils.setFrostTheme
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/FrostWebActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/FrostWebActivity.kt
similarity index 92%
rename from app/src/main/kotlin/com/pitchedapps/frost/FrostWebActivity.kt
rename to app/src/main/kotlin/com/pitchedapps/frost/activities/FrostWebActivity.kt
index 3e337813bdd..1773471fc2a 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/FrostWebActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/FrostWebActivity.kt
@@ -1,4 +1,4 @@
-package com.pitchedapps.frost
+package com.pitchedapps.frost.activities
import android.os.Bundle
import com.pitchedapps.frost.utils.Prefs
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/ImageActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/ImageActivity.kt
new file mode 100644
index 00000000000..509ac2cb22d
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/ImageActivity.kt
@@ -0,0 +1,297 @@
+package com.pitchedapps.frost.activities
+
+import android.animation.ValueAnimator
+import android.annotation.SuppressLint
+import android.content.Intent
+import android.content.res.ColorStateList
+import android.graphics.Bitmap
+import android.graphics.Color
+import android.graphics.drawable.Drawable
+import android.net.Uri
+import android.os.Bundle
+import android.os.Environment
+import android.support.design.widget.FloatingActionButton
+import android.support.v4.content.FileProvider
+import android.support.v7.app.AppCompatActivity
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ProgressBar
+import android.widget.TextView
+import ca.allanwang.kau.permissions.PERMISSION_WRITE_EXTERNAL_STORAGE
+import ca.allanwang.kau.permissions.kauOnRequestPermissionsResult
+import ca.allanwang.kau.permissions.kauRequestPermissions
+import ca.allanwang.kau.utils.*
+import com.bumptech.glide.request.target.BaseTarget
+import com.bumptech.glide.request.target.SizeReadyCallback
+import com.bumptech.glide.request.target.Target
+import com.bumptech.glide.request.transition.Transition
+import com.davemorrissey.labs.subscaleview.ImageSource
+import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
+import com.mikepenz.google_material_typeface_library.GoogleMaterial
+import com.mikepenz.iconics.typeface.IIcon
+import com.pitchedapps.frost.BuildConfig
+import com.pitchedapps.frost.R
+import com.pitchedapps.frost.utils.*
+import com.sothree.slidinguppanel.SlidingUpPanelLayout
+import org.jetbrains.anko.doAsync
+import org.jetbrains.anko.uiThread
+import timber.log.Timber
+import java.io.File
+import java.io.IOException
+import java.text.SimpleDateFormat
+import java.util.*
+
+/**
+ * Created by Allan Wang on 2017-07-15.
+ */
+class ImageActivity : AppCompatActivity() {
+
+ val progress: ProgressBar by bindView(R.id.image_progress)
+ val container: ViewGroup by bindView(R.id.image_container)
+ val panel: SlidingUpPanelLayout? by bindOptionalView(R.id.image_panel)
+ val photo: SubsamplingScaleImageView by bindView(R.id.image_photo)
+ val caption: TextView? by bindOptionalView(R.id.image_text)
+ val fab: FloatingActionButton by bindView(R.id.image_fab)
+
+ /**
+ * Reference to the temporary file path
+ * Should be nonnull if the image is successfully loaded
+ * As this is temporary, the image is deleted upon exit
+ */
+ internal var tempFilePath: String? = null
+ /**
+ * Reference to path for downloaded image
+ * Nonnull once the image is downloaded by the user
+ */
+ internal var downloadPath: String? = null
+ /**
+ * Indicator for fab's click result
+ */
+ internal var fabAction: FabStates = FabStates.NOTHING
+ set(value) {
+ if (field == value) return
+ field = value
+ value.update(fab)
+ }
+
+ val imageUrl: String
+ get() = intent.extras.getString(ARG_IMAGE_URL)
+
+ val text: String?
+ get() = intent.extras.getString(ARG_TEXT)
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(if (!text.isNullOrBlank()) R.layout.activity_image else R.layout.activity_image_textless)
+ container.setBackgroundColor(Prefs.bgColor.withMinAlpha(222))
+ caption?.setTextColor(Prefs.textColor)
+ caption?.setBackgroundColor(Prefs.bgColor.colorToForeground(0.1f).withAlpha(255))
+ caption?.text = text
+ progress.tint(Prefs.accentColor)
+ panel?.addPanelSlideListener(object : SlidingUpPanelLayout.SimplePanelSlideListener() {
+
+ override fun onPanelSlide(panel: View, slideOffset: Float) {
+ if (slideOffset == 0f && !fab.isShown) fab.show()
+ else if (slideOffset != 0f && fab.isShown) fab.hide()
+ caption?.alpha = slideOffset / 2 + 0.5f
+ }
+
+ })
+ fab.setOnClickListener { fabAction.onClick(this) }
+ photo.setOnImageEventListener(object : SubsamplingScaleImageView.DefaultOnImageEventListener() {
+ override fun onImageLoadError(e: Exception) {
+ L.e(e, "Image load error")
+ imageCallback(null, false)
+ }
+ })
+ GlideApp.with(this).asBitmap().load(imageUrl).into(PhotoTarget(this::imageCallback))
+ }
+
+ /**
+ * Callback to add image to view
+ * [resource] is guaranteed to be nonnull when [success] is true
+ * and null when it is false
+ */
+ private fun imageCallback(resource: Bitmap?, success: Boolean) {
+ if (progress.isVisible) progress.fadeOut()
+ if (success) {
+ saveTempImage(resource!!, {
+ if (it == null) {
+ imageCallback(null, false)
+ } else {
+ photo.setImage(ImageSource.uri(it))
+ fabAction = FabStates.DOWNLOAD
+ photo.animate().alpha(1f).scaleX(1f).scaleY(1f).withEndAction { fab.show() }.start()
+ }
+ })
+ } else {
+ fabAction = FabStates.ERROR
+ fab.show()
+ }
+ }
+
+ /**
+ * Bitmap load handler
+ */
+ class PhotoTarget(val callback: (resource: Bitmap?, success: Boolean) -> Unit) : BaseTarget() {
+
+ override fun removeCallback(cb: SizeReadyCallback?) {}
+
+ override fun onResourceReady(resource: Bitmap, transition: Transition?) = callback(resource, true)
+
+ override fun onLoadFailed(errorDrawable: Drawable?) = callback(null, false)
+
+ override fun getSize(cb: SizeReadyCallback) = cb.onSizeReady(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
+
+ }
+
+ private fun saveTempImage(resource: Bitmap, callback: (uri: Uri?) -> Unit) {
+ var photoFile: File? = null
+ try {
+ photoFile = createImageFile()
+ } catch (ignored: IOException) {
+ } finally {
+ if (photoFile == null) {
+ callback(null)
+ } else {
+ tempFilePath = photoFile.absolutePath
+ Timber.d("Temp image path $tempFilePath")
+ // File created; proceed with request
+ val photoURI = FileProvider.getUriForFile(this,
+ BuildConfig.APPLICATION_ID + ".provider",
+ photoFile)
+ photoFile.outputStream().use { resource.compress(Bitmap.CompressFormat.PNG, 100, it) }
+ callback(photoURI)
+ }
+ }
+ }
+
+ @Suppress("SIMPLE_DATE_FORMAT")
+ @Throws(IOException::class)
+ private fun createImageFile(): File {
+ // Create an image file name
+ @SuppressLint("SimpleDateFormat")
+ val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
+ val imageFileName = "Frost_" + timeStamp + "_"
+ val storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES)
+ return File.createTempFile(
+ imageFileName, /* prefix */
+ ".png", /* suffix */
+ storageDir /* directory */
+ )
+ }
+
+ internal fun downloadImage() {
+ kauRequestPermissions(PERMISSION_WRITE_EXTERNAL_STORAGE) {
+ granted, _ ->
+ if (granted) {
+ doAsync {
+ val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
+ val imageFileName = "Frost_" + timeStamp + "_"
+ val storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
+ val frostDir = File(storageDir, "Frost")
+ if (!frostDir.exists()) frostDir.mkdirs()
+ val destination = File.createTempFile(imageFileName, ".png", frostDir)
+ downloadPath = destination.absolutePath
+ var success = true
+ try {
+ File(tempFilePath).copyTo(destination, true)
+ } catch (e: Exception) {
+ success = false
+ } finally {
+ uiThread {
+ snackbar(if (success) R.string.image_download_success else R.string.image_download_fail)
+ if (success) {
+ deleteTempFile()
+ fabAction = FabStates.SHARE
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ internal fun deleteTempFile() {
+ if (tempFilePath != null) {
+ File(tempFilePath!!).delete()
+ tempFilePath = null
+ }
+ }
+
+ override fun onDestroy() {
+ deleteTempFile()
+ super.onDestroy()
+ }
+
+ override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults)
+ kauOnRequestPermissionsResult(permissions, grantResults)
+ }
+}
+
+internal enum class FabStates(val iicon: IIcon, val iconColor: Int = Prefs.textColor, val backgroundTint: Int = Prefs.accentBackgroundColor.withAlpha(255)) {
+ ERROR(GoogleMaterial.Icon.gmd_error, Color.WHITE, Color.RED) {
+ override fun onClick(activity: ImageActivity) {
+ //todo add something
+ }
+ },
+ NOTHING(GoogleMaterial.Icon.gmd_adjust) {
+ override fun onClick(activity: ImageActivity) {}
+ },
+ DOWNLOAD(GoogleMaterial.Icon.gmd_file_download) {
+ override fun onClick(activity: ImageActivity) {
+ activity.downloadImage()
+ }
+ },
+ SHARE(GoogleMaterial.Icon.gmd_share) {
+ override fun onClick(activity: ImageActivity) {
+ try {
+ val photoURI = FileProvider.getUriForFile(activity,
+ BuildConfig.APPLICATION_ID + ".provider",
+ File(activity.downloadPath))
+ val intent = Intent(Intent.ACTION_SEND).apply {
+ flags = Intent.FLAG_ACTIVITY_NEW_TASK
+ putExtra(Intent.EXTRA_STREAM, photoURI)
+ type = "image/png"
+ }
+ activity.startActivity(intent)
+ } catch (e: Exception) {
+ L.e(e, "Image share failed");
+ activity.snackbar(R.string.image_share_failed)
+ }
+ }
+ };
+
+ /**
+ * Change the fab look
+ * If it's in view, give it some animations
+ */
+ fun update(fab: FloatingActionButton) {
+ if (!fab.isShown) {
+ fab.setIcon(iicon, color = iconColor)
+ fab.backgroundTintList = ColorStateList.valueOf(backgroundTint)
+ } else {
+ var switched = false
+ ValueAnimator.ofFloat(1.0f, 0.0f, 1.0f).apply {
+ duration = 500L
+ addUpdateListener {
+ val x = it.animatedValue as Float
+ val scale = x * 0.3f + 0.7f
+ fab.scaleX = scale
+ fab.scaleY = scale
+ fab.imageAlpha = (x * 255).toInt()
+ if (it.animatedFraction > 0.5f && !switched) {
+ switched = true
+ fab.setIcon(iicon, color = iconColor)
+ fab.backgroundTintList = ColorStateList.valueOf(backgroundTint)
+ }
+ }
+ start()
+ }
+ }
+ }
+
+ abstract fun onClick(activity: ImageActivity)
+
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/LoginActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt
similarity index 98%
rename from app/src/main/kotlin/com/pitchedapps/frost/LoginActivity.kt
rename to app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt
index a27a1ee2b73..e4897be552e 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/LoginActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt
@@ -1,4 +1,4 @@
-package com.pitchedapps.frost
+package com.pitchedapps.frost.activities
import android.graphics.drawable.Drawable
import android.os.Bundle
@@ -16,6 +16,7 @@ import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.target.Target
import com.crashlytics.android.answers.LoginEvent
+import com.pitchedapps.frost.R
import com.pitchedapps.frost.dbflow.CookieModel
import com.pitchedapps.frost.dbflow.fetchUsername
import com.pitchedapps.frost.dbflow.loadFbCookiesAsync
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/MainActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt
similarity index 97%
rename from app/src/main/kotlin/com/pitchedapps/frost/MainActivity.kt
rename to app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt
index f9a597db3f4..ba76e594b7d 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/MainActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt
@@ -1,4 +1,4 @@
-package com.pitchedapps.frost
+package com.pitchedapps.frost.activities
import android.app.AlarmManager
import android.app.PendingIntent
@@ -39,6 +39,8 @@ import com.mikepenz.google_material_typeface_library.GoogleMaterial
import com.mikepenz.iconics.IconicsDrawable
import com.mikepenz.materialdrawer.AccountHeader
import com.mikepenz.materialdrawer.Drawer
+import com.pitchedapps.frost.BuildConfig
+import com.pitchedapps.frost.R
import com.pitchedapps.frost.contracts.ActivityWebContract
import com.pitchedapps.frost.contracts.FileChooserContract
import com.pitchedapps.frost.contracts.FileChooserDelegate
@@ -107,7 +109,15 @@ class MainActivity : BaseActivity(), FrostWebViewSearch.SearchContract,
super.onCreate(savedInstanceState)
if (BuildConfig.VERSION_CODE > Prefs.versionCode) {
Prefs.versionCode = BuildConfig.VERSION_CODE
- if (!BuildConfig.DEBUG) showChangelog(R.xml.changelog, Prefs.textColor) { theme() }
+ if (!BuildConfig.DEBUG) {
+ showChangelog(R.xml.changelog, Prefs.textColor) { theme() }
+ frostAnswersCustom("Version") {
+ putCustomAttribute("Version code", BuildConfig.VERSION_CODE)
+ putCustomAttribute("Version name", BuildConfig.VERSION_NAME)
+ putCustomAttribute("Build type", BuildConfig.BUILD_TYPE)
+ putCustomAttribute("Frost id", Prefs.frostId)
+ }
+ }
}
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/SelectorActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/SelectorActivity.kt
similarity index 96%
rename from app/src/main/kotlin/com/pitchedapps/frost/SelectorActivity.kt
rename to app/src/main/kotlin/com/pitchedapps/frost/activities/SelectorActivity.kt
index 103ae227476..ff87f44839a 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/SelectorActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/SelectorActivity.kt
@@ -1,4 +1,4 @@
-package com.pitchedapps.frost
+package com.pitchedapps.frost.activities
import android.os.Bundle
import android.support.constraint.ConstraintLayout
@@ -10,6 +10,7 @@ import ca.allanwang.kau.utils.bindView
import com.mikepenz.fastadapter.FastAdapter
import com.mikepenz.fastadapter.commons.adapters.FastItemAdapter
import com.mikepenz.fastadapter.listeners.ClickEventHook
+import com.pitchedapps.frost.R
import com.pitchedapps.frost.facebook.FbCookie
import com.pitchedapps.frost.utils.cookies
import com.pitchedapps.frost.utils.launchNewTask
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/SettingsActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/SettingsActivity.kt
similarity index 97%
rename from app/src/main/kotlin/com/pitchedapps/frost/SettingsActivity.kt
rename to app/src/main/kotlin/com/pitchedapps/frost/activities/SettingsActivity.kt
index e0be330d191..b3b3bd7ca1c 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/SettingsActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/SettingsActivity.kt
@@ -1,4 +1,4 @@
-package com.pitchedapps.frost
+package com.pitchedapps.frost.activities
import android.content.Intent
import android.os.Bundle
@@ -13,6 +13,8 @@ import ca.allanwang.kau.ui.views.RippleCanvas
import ca.allanwang.kau.utils.*
import com.mikepenz.community_material_typeface_library.CommunityMaterial
import com.mikepenz.google_material_typeface_library.GoogleMaterial
+import com.pitchedapps.frost.BuildConfig
+import com.pitchedapps.frost.R
import com.pitchedapps.frost.settings.*
import com.pitchedapps.frost.utils.*
import com.pitchedapps.frost.utils.iab.*
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/WebOverlayActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/WebOverlayActivity.kt
similarity index 98%
rename from app/src/main/kotlin/com/pitchedapps/frost/WebOverlayActivity.kt
rename to app/src/main/kotlin/com/pitchedapps/frost/activities/WebOverlayActivity.kt
index 6c1fb5bd11d..f03c653c8fa 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/WebOverlayActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/WebOverlayActivity.kt
@@ -1,4 +1,4 @@
-package com.pitchedapps.frost
+package com.pitchedapps.frost.activities
import android.content.Intent
import android.net.Uri
@@ -18,6 +18,7 @@ import ca.allanwang.kau.swipe.kauSwipeOnPostCreate
import ca.allanwang.kau.utils.*
import com.mikepenz.community_material_typeface_library.CommunityMaterial
import com.mikepenz.google_material_typeface_library.GoogleMaterial
+import com.pitchedapps.frost.R
import com.pitchedapps.frost.contracts.ActivityWebContract
import com.pitchedapps.frost.contracts.FileChooserContract
import com.pitchedapps.frost.contracts.FileChooserDelegate
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbConst.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbConst.kt
index e521688192f..4d5127c55d4 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbConst.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbConst.kt
@@ -8,6 +8,6 @@ const val FACEBOOK_COM = "facebook.com"
const val FB_URL_BASE = "https://m.facebook.com/"
fun PROFILE_PICTURE_URL(id: Long) = "https://graph.facebook.com/$id/picture?type=large"
-const val USER_AGENT_BASIC_FULL = "Mozilla/5.0 (Linux; Android 4.4.2; en-us; SAMSUNG SM-G900T Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Version/1.6 Chrome/28.0.1500.94 Mobile Safari/537.36"
+const val USER_AGENT_FULL = "Mozilla/5.0 (Linux; Android 4.4.2; en-us; SAMSUNG SM-G900T Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Version/1.6 Chrome/28.0.1500.94 Mobile Safari/537.36"
const val USER_AGENT_BASIC = "Mozilla/5.0 (Linux; U; Android 2.3.3; en-gb; Nexus S Build/GRI20) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1"
const val USER_AGENT_MESSENGER = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36"
\ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbUrlFormatter.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbUrlFormatter.kt
index e53bb202016..622be067977 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbUrlFormatter.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbUrlFormatter.kt
@@ -14,10 +14,10 @@ class FbUrlFormatter(url: String) {
init {
var cleanedUrl = url
- discardable.forEach { cleanedUrl = cleanedUrl.replace(it, "") }
+ discardable.forEach { cleanedUrl = cleanedUrl.replace(it, "", true) }
val changed = cleanedUrl != url //note that discardables strip away the first ?
- decoder.forEach { (k, v) -> cleanedUrl = cleanedUrl.replace(k, v) }
- val qm = cleanedUrl.indexOf(if (changed)"&" else "?")
+ decoder.forEach { (k, v) -> cleanedUrl = cleanedUrl.replace(k, v, true) }
+ val qm = cleanedUrl.indexOf(if (changed) "&" else "?")
if (qm > -1) {
cleanedUrl.substring(qm + 1).split("&").forEach {
val p = it.split("=")
@@ -72,7 +72,15 @@ class FbUrlFormatter(url: String) {
"%60" to "`", "%3B" to ";", "%2F" to "/", "%3F" to "?",
"%3A" to ":", "%40" to "@", "%3D" to "=", "%26" to "&",
"%24" to "$", "%2B" to "+", "%22" to "\"", "%2C" to ",",
- "%20" to " "
+ "%20" to " ",
+ //css
+ "\\3C " to "<", "\\3E " to ">", "\\23 " to "#", "\\25 " to "%",
+ "\\7B " to "{", "\\7D " to "}", "\\7C " to "|", "\\5C " to "\\",
+ "\\5E " to "^", "\\7E " to "~", "\\5B " to "[", "\\5D " to "]",
+ "\\60 " to "`", "\\3B " to ";", "\\2F " to "/", "\\3F " to "?",
+ "\\3A " to ":", "\\40 " to "@", "\\3D " to "=", "\\26 " to "&",
+ "\\24 " to "$", "\\2B " to "+", "\\22 " to "\"", "\\2C " to ",",
+ "\\20 " to " "
)
}
}
\ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/fragments/WebFragment.kt b/app/src/main/kotlin/com/pitchedapps/frost/fragments/WebFragment.kt
index 87afc434dc4..239f5842a48 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/fragments/WebFragment.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/fragments/WebFragment.kt
@@ -7,7 +7,7 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import ca.allanwang.kau.utils.withArguments
-import com.pitchedapps.frost.MainActivity
+import com.pitchedapps.frost.activities.MainActivity
import com.pitchedapps.frost.facebook.FbTab
import com.pitchedapps.frost.facebook.FeedSort
import com.pitchedapps.frost.utils.Prefs
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/services/FrostNotifications.kt b/app/src/main/kotlin/com/pitchedapps/frost/services/FrostNotifications.kt
index 7b60a7187a9..737b86aba90 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/services/FrostNotifications.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/services/FrostNotifications.kt
@@ -17,7 +17,7 @@ import ca.allanwang.kau.utils.string
import com.bumptech.glide.request.target.SimpleTarget
import com.bumptech.glide.request.transition.Transition
import com.pitchedapps.frost.BuildConfig
-import com.pitchedapps.frost.FrostWebActivity
+import com.pitchedapps.frost.activities.FrostWebActivity
import com.pitchedapps.frost.R
import com.pitchedapps.frost.dbflow.CookieModel
import com.pitchedapps.frost.dbflow.fetchUsername
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/settings/Appearance.kt b/app/src/main/kotlin/com/pitchedapps/frost/settings/Appearance.kt
index e05d0dd3e74..e814e1ac9a0 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/settings/Appearance.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/settings/Appearance.kt
@@ -5,9 +5,9 @@ import ca.allanwang.kau.kpref.activity.items.KPrefColorPicker
import ca.allanwang.kau.kpref.activity.items.KPrefSeekbar
import ca.allanwang.kau.ui.views.RippleCanvas
import ca.allanwang.kau.utils.string
-import com.pitchedapps.frost.MainActivity
+import com.pitchedapps.frost.activities.MainActivity
import com.pitchedapps.frost.R
-import com.pitchedapps.frost.SettingsActivity
+import com.pitchedapps.frost.activities.SettingsActivity
import com.pitchedapps.frost.injectors.CssAssets
import com.pitchedapps.frost.utils.*
import com.pitchedapps.frost.utils.iab.IS_FROST_PRO
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/settings/Behaviour.kt b/app/src/main/kotlin/com/pitchedapps/frost/settings/Behaviour.kt
index 7ce546b3592..e7cf359862f 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/settings/Behaviour.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/settings/Behaviour.kt
@@ -1,9 +1,9 @@
package com.pitchedapps.frost.settings
import ca.allanwang.kau.kpref.activity.KPrefAdapterBuilder
-import com.pitchedapps.frost.MainActivity
+import com.pitchedapps.frost.activities.MainActivity
import com.pitchedapps.frost.R
-import com.pitchedapps.frost.SettingsActivity
+import com.pitchedapps.frost.activities.SettingsActivity
import com.pitchedapps.frost.utils.Prefs
/**
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/settings/Experimental.kt b/app/src/main/kotlin/com/pitchedapps/frost/settings/Experimental.kt
index 86bd356bfcf..236d19f9fcf 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/settings/Experimental.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/settings/Experimental.kt
@@ -1,9 +1,9 @@
package com.pitchedapps.frost.settings
import ca.allanwang.kau.kpref.activity.KPrefAdapterBuilder
-import com.pitchedapps.frost.MainActivity
+import com.pitchedapps.frost.activities.MainActivity
import com.pitchedapps.frost.R
-import com.pitchedapps.frost.SettingsActivity
+import com.pitchedapps.frost.activities.SettingsActivity
import com.pitchedapps.frost.utils.Prefs
import com.pitchedapps.frost.utils.Showcase
@@ -20,10 +20,14 @@ fun SettingsActivity.getExperimentalPrefs(): KPrefAdapterBuilder.() -> Unit = {
descRes = R.string.experimental_by_default_desc
}
+ // Experimental content starts here ------------------
+
checkbox(R.string.search_bar, { Prefs.searchBar }, { Prefs.searchBar = it; setResult(MainActivity.REQUEST_SEARCH) }) {
descRes = R.string.search_bar_desc
}
+ // Experimental content ends here --------------------
+
checkbox(R.string.verbose_logging, { Prefs.verboseLogging }, { Prefs.verboseLogging = it }) {
descRes = R.string.verbose_logging_desc
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/settings/Feed.kt b/app/src/main/kotlin/com/pitchedapps/frost/settings/Feed.kt
index 29256950ae4..689e6bdb777 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/settings/Feed.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/settings/Feed.kt
@@ -2,9 +2,9 @@ package com.pitchedapps.frost.settings
import ca.allanwang.kau.kpref.activity.KPrefAdapterBuilder
import ca.allanwang.kau.utils.string
-import com.pitchedapps.frost.MainActivity
+import com.pitchedapps.frost.activities.MainActivity
import com.pitchedapps.frost.R
-import com.pitchedapps.frost.SettingsActivity
+import com.pitchedapps.frost.activities.SettingsActivity
import com.pitchedapps.frost.facebook.FeedSort
import com.pitchedapps.frost.utils.Prefs
import com.pitchedapps.frost.utils.materialDialogThemed
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/settings/Notifications.kt b/app/src/main/kotlin/com/pitchedapps/frost/settings/Notifications.kt
index b610505418a..59ebf7009bb 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/settings/Notifications.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/settings/Notifications.kt
@@ -4,7 +4,7 @@ import ca.allanwang.kau.kpref.activity.KPrefAdapterBuilder
import ca.allanwang.kau.utils.minuteToText
import ca.allanwang.kau.utils.snackbar
import com.pitchedapps.frost.R
-import com.pitchedapps.frost.SettingsActivity
+import com.pitchedapps.frost.activities.SettingsActivity
import com.pitchedapps.frost.services.fetchNotifications
import com.pitchedapps.frost.services.scheduleNotifications
import com.pitchedapps.frost.utils.Prefs
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt
index d2e04898326..f8c7af563c5 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt
@@ -4,6 +4,7 @@ import ca.allanwang.kau.kotlin.lazyResettable
import ca.allanwang.kau.kpref.KPref
import ca.allanwang.kau.kpref.StringSet
import ca.allanwang.kau.kpref.kpref
+import ca.allanwang.kau.utils.colorToForeground
import ca.allanwang.kau.utils.isColorVisibleOn
import com.pitchedapps.frost.facebook.FeedSort
import com.pitchedapps.frost.injectors.InjectorContract
@@ -57,9 +58,24 @@ object Prefs : KPref() {
val iconColor: Int
get() = t.iconColor
+ /**
+ * Ensures that the color is visible against the background
+ */
val accentColor: Int
get() = if (headerColor.isColorVisibleOn(bgColor, 100)) headerColor else textColor
+ /**
+ * Ensures that the color is visible against both the foreground and background
+ */
+ val accentBackgroundColor: Int
+ get() {
+ if (headerColor.isColorVisibleOn(textColor, 100)) {
+ if (headerColor.isColorVisibleOn(bgColor, 100)) return headerColor
+ else return headerColor.colorToForeground(0.2f)
+ }
+ return bgColor.colorToForeground(0.2f)
+ }
+
val themeInjector: InjectorContract
get() = t.injector
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt
index 9a599945f56..c0db8308e58 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt
@@ -8,19 +8,27 @@ import android.support.annotation.StringRes
import android.support.design.internal.SnackbarContentLayout
import android.support.design.widget.Snackbar
import android.support.v7.widget.Toolbar
+import android.util.Log
import android.view.View
import android.widget.FrameLayout
import android.widget.TextView
import ca.allanwang.kau.utils.*
import com.afollestad.materialdialogs.MaterialDialog
+import com.bumptech.glide.GlideBuilder
import com.bumptech.glide.RequestBuilder
+import com.bumptech.glide.annotation.GlideExtension
import com.bumptech.glide.annotation.GlideModule
import com.bumptech.glide.load.resource.bitmap.CircleCrop
import com.bumptech.glide.module.AppGlideModule
import com.bumptech.glide.request.RequestOptions
import com.crashlytics.android.answers.Answers
import com.crashlytics.android.answers.CustomEvent
-import com.pitchedapps.frost.*
+import com.pitchedapps.frost.BuildConfig
+import com.pitchedapps.frost.R
+import com.pitchedapps.frost.activities.ImageActivity
+import com.pitchedapps.frost.activities.LoginActivity
+import com.pitchedapps.frost.activities.SelectorActivity
+import com.pitchedapps.frost.activities.WebOverlayActivity
import com.pitchedapps.frost.dbflow.CookieModel
import com.pitchedapps.frost.facebook.FbTab
import com.pitchedapps.frost.facebook.formattedFbUrl
@@ -31,6 +39,8 @@ import com.pitchedapps.frost.facebook.formattedFbUrl
const val EXTRA_COOKIES = "extra_cookies"
const val ARG_URL = "arg_url"
const val ARG_USER_ID = "arg_user_id"
+const val ARG_IMAGE_URL = "arg_image_url"
+const val ARG_TEXT = "arg_text"
@GlideModule
class FrostGlideModule : AppGlideModule()
@@ -59,6 +69,13 @@ fun Context.launchWebOverlay(url: String) {
})
}
+fun Context.launchImageActivity(imageUrl: String, text: String?) {
+ startActivity(ImageActivity::class.java, intentBuilder = {
+ putExtra(ARG_IMAGE_URL, imageUrl)
+ putExtra(ARG_TEXT, text)
+ })
+}
+
fun WebOverlayActivity.url(): String {
return intent.extras?.getString(ARG_URL) ?: FbTab.FEED.url
}
@@ -131,4 +148,4 @@ fun Activity.frostNavigationBar() {
navigationBarColor = if (Prefs.tintNavBar) Prefs.headerColor else Color.BLACK
}
-fun RequestBuilder.withRoundIcon() = apply(RequestOptions().transform(CircleCrop()))
+fun RequestBuilder.withRoundIcon() = apply(RequestOptions().transform(CircleCrop()))
\ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/WebContextMenu.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/WebContextMenu.kt
index 67c20a5a47d..17ea46a3d37 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/WebContextMenu.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/WebContextMenu.kt
@@ -4,7 +4,8 @@ import android.content.Context
import ca.allanwang.kau.utils.copyToClipboard
import ca.allanwang.kau.utils.shareText
import ca.allanwang.kau.utils.string
-import com.pitchedapps.frost.MainActivity
+import ca.allanwang.kau.utils.toast
+import com.pitchedapps.frost.activities.MainActivity
import com.pitchedapps.frost.R
/**
@@ -18,7 +19,10 @@ fun Context.showWebContextMenu(wc: WebContext) {
materialDialogThemed {
title(title)
- items(WebContextType.values.map { this@showWebContextMenu.string(it.textId) })
+ items(WebContextType.values.map {
+ if (it == WebContextType.COPY_TEXT && wc.text == null) return@map null
+ this@showWebContextMenu.string(it.textId)
+ }.filterNotNull())
itemsCallback {
_, _, position, _ ->
WebContextType[position].onClick(this@showWebContextMenu, wc)
@@ -30,11 +34,11 @@ fun Context.showWebContextMenu(wc: WebContext) {
}
}
-class WebContext(val url: String, val text: String)
+class WebContext(val url: String, val text: String?)
enum class WebContextType(val textId: Int, val onClick: (c: Context, wc: WebContext) -> Unit) {
COPY_LINK(R.string.copy_link, { c, wc -> c.copyToClipboard(wc.url) }),
- COPY_TEXT(R.string.copy_text, { c, wc -> c.copyToClipboard(wc.text) }),
+ COPY_TEXT(R.string.copy_text, { c, wc -> if (wc.text != null) c.copyToClipboard(wc.text) else c.toast(R.string.no_text) }),
SHARE_LINK(R.string.share_link, { c, wc -> c.shareText(wc.url) })
;
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/iab/IAB.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/iab/IAB.kt
index 58c748c2bd0..964e771c5f7 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/iab/IAB.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/iab/IAB.kt
@@ -9,7 +9,7 @@ import ca.allanwang.kau.utils.snackbar
import com.crashlytics.android.answers.PurchaseEvent
import com.pitchedapps.frost.BuildConfig
import com.pitchedapps.frost.R
-import com.pitchedapps.frost.SettingsActivity
+import com.pitchedapps.frost.activities.SettingsActivity
import com.pitchedapps.frost.utils.*
/**
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/iab/IABDialogs.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/iab/IABDialogs.kt
index 4f65b7f85d8..fae2f6bb930 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/iab/IABDialogs.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/iab/IABDialogs.kt
@@ -4,9 +4,9 @@ import android.app.Activity
import ca.allanwang.kau.utils.restart
import ca.allanwang.kau.utils.startPlayStoreLink
import ca.allanwang.kau.utils.string
-import com.pitchedapps.frost.MainActivity
+import com.pitchedapps.frost.activities.MainActivity
import com.pitchedapps.frost.R
-import com.pitchedapps.frost.SettingsActivity
+import com.pitchedapps.frost.activities.SettingsActivity
import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.utils.Prefs
import com.pitchedapps.frost.utils.materialDialogThemed
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/BaseWebViewClient.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/BaseWebViewClient.kt
new file mode 100644
index 00000000000..09241254b82
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/BaseWebViewClient.kt
@@ -0,0 +1,16 @@
+package com.pitchedapps.frost.web
+
+import android.webkit.WebResourceRequest
+import android.webkit.WebResourceResponse
+import android.webkit.WebView
+import android.webkit.WebViewClient
+
+/**
+ * Created by Allan Wang on 2017-07-13.
+ */
+open class BaseWebViewClient : WebViewClient() {
+
+ override fun shouldInterceptRequest(view: WebView, request: WebResourceRequest): WebResourceResponse?
+ = shouldFrostInterceptRequest(view, request)
+
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClient.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClient.kt
index aab3a165378..4df6d6a7b43 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClient.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClient.kt
@@ -1,9 +1,10 @@
package com.pitchedapps.frost.web
import android.net.Uri
-import android.os.Message
-import android.view.View
-import android.webkit.*
+import android.webkit.ConsoleMessage
+import android.webkit.ValueCallback
+import android.webkit.WebChromeClient
+import android.webkit.WebView
import ca.allanwang.kau.utils.snackbar
import com.pitchedapps.frost.contracts.ActivityWebContract
import com.pitchedapps.frost.utils.L
@@ -20,9 +21,16 @@ class FrostChromeClient(webCore: FrostWebViewCore) : WebChromeClient() {
val titleObservable: BehaviorSubject = webCore.titleObservable
val activityContract = (webCore.context as? ActivityWebContract)
+ companion object {
+ val consoleBlacklist = setOf(
+ "edge-chat"
+ )
+ }
+
override fun onConsoleMessage(consoleMessage: ConsoleMessage): Boolean {
+ if (consoleBlacklist.any { consoleMessage.message().contains(it) }) return true
L.i("Chrome Console ${consoleMessage.lineNumber()}: ${consoleMessage.message()}")
- return super.onConsoleMessage(consoleMessage)
+ return true
}
override fun onReceivedTitle(view: WebView, title: String) {
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt
index 3340e7d2017..3f976fb8323 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt
@@ -2,8 +2,9 @@ package com.pitchedapps.frost.web
import android.content.Context
import android.webkit.JavascriptInterface
-import ca.allanwang.kau.logging.KL
-import com.pitchedapps.frost.MainActivity
+import ca.allanwang.kau.utils.startActivity
+import com.pitchedapps.frost.activities.ImageActivity
+import com.pitchedapps.frost.activities.MainActivity
import com.pitchedapps.frost.dbflow.CookieModel
import com.pitchedapps.frost.facebook.formattedFbUrl
import com.pitchedapps.frost.utils.*
@@ -13,12 +14,18 @@ import io.reactivex.subjects.Subject
/**
* Created by Allan Wang on 2017-06-01.
*/
-class FrostJSI(val context: Context, val webView: FrostWebViewCore) {
+class FrostJSI(val webView: FrostWebViewCore) {
- val headerObservable: Subject? = (context as? MainActivity)?.headerBadgeObservable
+ val context: Context
+ get() = webView.context
+
+ val activity: MainActivity?
+ get() = (context as? MainActivity)
+
+ val headerObservable: Subject? = activity?.headerBadgeObservable
val cookies: ArrayList
- get() = (context as? MainActivity)?.cookies() ?: arrayListOf()
+ get() = activity?.cookies() ?: arrayListOf()
@JavascriptInterface
fun loadUrl(url: String) {
@@ -35,8 +42,8 @@ class FrostJSI(val context: Context, val webView: FrostWebViewCore) {
}
@JavascriptInterface
- fun contextMenu(url: String, text: String) {
- webView.post { webView.context.showWebContextMenu(WebContext(url.formattedFbUrl, text)) }
+ fun contextMenu(url: String, text: String?) {
+ webView.post { context.showWebContextMenu(WebContext(url.formattedFbUrl, text)) }
}
/**
@@ -45,7 +52,7 @@ class FrostJSI(val context: Context, val webView: FrostWebViewCore) {
*/
@JavascriptInterface
fun longClick(start: Boolean) {
- (webView.context as? MainActivity)?.viewPager?.enableSwipe = !start
+ activity?.viewPager?.enableSwipe = !start
}
@JavascriptInterface
@@ -53,6 +60,14 @@ class FrostJSI(val context: Context, val webView: FrostWebViewCore) {
context.launchLogin(cookies, true)
}
+ /**
+ * Launch image overlay
+ */
+ @JavascriptInterface
+ fun loadImage(imageUrl: String, text: String?) {
+ context.launchImageActivity(imageUrl, text)
+ }
+
@JavascriptInterface
fun emit(flag: Int) {
webView.post { webView.frostWebClient.emit(flag) }
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostRequestInterceptor.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostRequestInterceptor.kt
new file mode 100644
index 00000000000..45dc83aa100
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostRequestInterceptor.kt
@@ -0,0 +1,67 @@
+package com.pitchedapps.frost.web
+
+import android.graphics.Bitmap.CompressFormat
+import android.webkit.WebResourceRequest
+import android.webkit.WebResourceResponse
+import android.webkit.WebView
+import ca.allanwang.kau.utils.use
+import com.pitchedapps.frost.utils.GlideApp
+import com.pitchedapps.frost.utils.L
+import com.pitchedapps.frost.utils.Prefs
+import okhttp3.HttpUrl
+import java.io.ByteArrayInputStream
+import java.io.ByteArrayOutputStream
+import java.io.InputStream
+
+
+/**
+ * Created by Allan Wang on 2017-07-13.
+ *
+ * Handler to decide when a request should be done by us
+ * This is the crux of Frost's optimizations for the web browser
+ */
+val blankResource: WebResourceResponse by lazy { WebResourceResponse("text/plain", "utf-8", ByteArrayInputStream("".toByteArray())) }
+
+//these hosts will redirect to a blank resource
+val blacklistHost: Set by lazy {
+ setOf(
+ "edge-chat.facebook.com"
+ )
+}
+
+//these hosts will return null and skip logging
+val whitelistHost: Set by lazy {
+ setOf(
+ "static.xx.fbcdn.net",
+ "m.facebook.com",
+ "touch.facebook.com"
+ )
+}
+
+//these hosts will skip ad inspection
+//this list does not have to include anything from the two above
+val adWhitelistHost: Set by lazy {
+ setOf(
+ "scontent-sea1-1.xx.fbcdn.net"
+ )
+}
+
+var adblock: Set? = null
+
+fun shouldFrostInterceptRequest(view: WebView, request: WebResourceRequest): WebResourceResponse? {
+ val httpUrl = HttpUrl.parse(request.url?.toString() ?: return null) ?: return null
+ val host = httpUrl.host()
+ val url = httpUrl.toString()
+ if (blacklistHost.contains(host)) return blankResource
+ if (whitelistHost.contains(host)) return null
+ if (!adWhitelistHost.contains(host)) {
+ if (adblock == null) adblock = view.context.assets.open("adblock.txt").bufferedReader().use { it.readLines().toSet() }
+ if (adblock?.any { url.contains(it) } ?: false) return blankResource
+ }
+ L.v("Intercept Request ${host} ${url}")
+ return null
+}
+
+fun WebResourceResponse?.filterCss(request: WebResourceRequest): WebResourceResponse?
+ = this ?: if (request.url.path.endsWith(".css")) blankResource else null
+
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebView.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebView.kt
index 7c0a659732a..e7dae22a109 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebView.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebView.kt
@@ -69,7 +69,7 @@ class FrostWebView @JvmOverloads constructor(
frostWebClient = baseEnum?.webClient?.invoke(this) ?: FrostWebViewClient(this)
webViewClient = frostWebClient
webChromeClient = FrostChromeClient(this)
- addJavascriptInterface(FrostJSI(context, this), "Frost")
+ addJavascriptInterface(FrostJSI(this), "Frost")
setBackgroundColor(Color.TRANSPARENT)
}
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClient.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClient.kt
index 5e5dc597dde..5b2b4bfd012 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClient.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClient.kt
@@ -4,10 +4,9 @@ import android.content.Context
import android.graphics.Bitmap
import android.webkit.WebResourceRequest
import android.webkit.WebView
-import android.webkit.WebViewClient
-import com.pitchedapps.frost.LoginActivity
-import com.pitchedapps.frost.MainActivity
-import com.pitchedapps.frost.SelectorActivity
+import com.pitchedapps.frost.activities.LoginActivity
+import com.pitchedapps.frost.activities.MainActivity
+import com.pitchedapps.frost.activities.SelectorActivity
import com.pitchedapps.frost.facebook.FACEBOOK_COM
import com.pitchedapps.frost.facebook.FbCookie
import com.pitchedapps.frost.injectors.*
@@ -17,7 +16,7 @@ import io.reactivex.subjects.Subject
/**
* Created by Allan Wang on 2017-05-31.
*/
-open class FrostWebViewClient(val webCore: FrostWebViewCore) : WebViewClient() {
+open class FrostWebViewClient(val webCore: FrostWebViewCore) : BaseWebViewClient() {
val refreshObservable: Subject = webCore.refreshObservable
@@ -97,15 +96,9 @@ open class FrostWebViewClient(val webCore: FrostWebViewCore) : WebViewClient() {
return super.shouldOverrideUrlLoading(view, request)
}
- override fun onPageCommitVisible(view: WebView?, url: String?) {
- L.d("ASDF PCV")
- super.onPageCommitVisible(view, url)
- }
-
-// override fun onLoadResource(view: WebView, url: String) {
-// L.v("Load resource $url")
-// super.onLoadResource(view, url)
+// override fun onPageCommitVisible(view: WebView?, url: String?) {
+// L.d("ASDF PCV")
+// super.onPageCommitVisible(view, url)
// }
-
}
\ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewCore.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewCore.kt
index 1e023dca6c7..d96fba55e43 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewCore.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewCore.kt
@@ -72,7 +72,7 @@ class FrostWebViewCore @JvmOverloads constructor(
dispose = refreshObservable.subscribeOn(AndroidSchedulers.mainThread()).subscribe {
if (it) {
loading = true
- if (isVisible()) fadeOut(duration = 200L)
+ if (isVisible) fadeOut(duration = 200L)
} else if (loading) {
dispose?.dispose()
if (animate && Prefs.animate) circularReveal(offset = 150L)
@@ -148,11 +148,12 @@ class FrostWebViewCore @JvmOverloads constructor(
if (scrollY > 10000) {
scrollTo(0, 0)
} else {
- val animator = ValueAnimator.ofInt(scrollY, 0)
- animator.duration = Math.min(scrollY, 500).toLong()
- animator.interpolator = DecelerateInterpolator()
- animator.addUpdateListener { scrollY = it.animatedValue as Int }
- animator.start()
+ ValueAnimator.ofInt(scrollY, 0).apply {
+ duration = Math.min(scrollY, 500).toLong()
+ interpolator = DecelerateInterpolator()
+ addUpdateListener { scrollY = it.animatedValue as Int }
+ start()
+ }
}
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewSearch.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewSearch.kt
index b3b1cfe5e10..bcadf32af30 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewSearch.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewSearch.kt
@@ -3,9 +3,7 @@ package com.pitchedapps.frost.web
import android.annotation.SuppressLint
import android.content.Context
import android.view.View
-import android.webkit.JavascriptInterface
-import android.webkit.WebView
-import android.webkit.WebViewClient
+import android.webkit.*
import ca.allanwang.kau.searchview.SearchItem
import ca.allanwang.kau.utils.gone
import com.pitchedapps.frost.facebook.FbTab
@@ -56,7 +54,8 @@ class FrostWebViewSearch(context: Context, val contract: SearchContract) : WebVi
settings.javaScriptEnabled = true
settings.userAgentString = USER_AGENT_BASIC
setLayerType(View.LAYER_TYPE_HARDWARE, null)
- webViewClient = FrostWebViewClientSearch()
+ webViewClient = SearchWebViewClient()
+ webChromeClient = SearchChromeClient()
addJavascriptInterface(SearchJSI(), "Frost")
searchSubject.debounce(300, TimeUnit.MILLISECONDS).subscribeOn(Schedulers.newThread())
.map {
@@ -111,13 +110,22 @@ class FrostWebViewSearch(context: Context, val contract: SearchContract) : WebVi
*
* Barebones client that does what [FrostWebViewSearch] needs
*/
- inner class FrostWebViewClientSearch : WebViewClient() {
+ inner class SearchWebViewClient : BaseWebViewClient() {
override fun onPageFinished(view: WebView, url: String) {
super.onPageFinished(view, url)
L.i("Search Page finished $url")
view.jsInject(JsAssets.SEARCH)
}
+
+ override fun shouldInterceptRequest(view: WebView, request: WebResourceRequest): WebResourceResponse?
+ = super.shouldInterceptRequest(view, request).filterCss(request)
+ }
+
+ class SearchChromeClient : WebChromeClient() {
+
+ //mute console
+ override fun onConsoleMessage(consoleMessage: ConsoleMessage) = true
}
inner class SearchJSI {
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/LoginWebView.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/LoginWebView.kt
index 38d4ad8ce63..d7a2db0a4ec 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/LoginWebView.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/LoginWebView.kt
@@ -66,7 +66,7 @@ class LoginWebView @JvmOverloads constructor(
}
- inner class LoginClient : WebViewClient() {
+ inner class LoginClient : BaseWebViewClient() {
override fun onPageFinished(view: WebView, url: String) {
super.onPageFinished(view, url)
@@ -88,7 +88,7 @@ class LoginWebView @JvmOverloads constructor(
inner class LoginChromeClient : WebChromeClient() {
override fun onConsoleMessage(consoleMessage: ConsoleMessage): Boolean {
L.d("Login Console ${consoleMessage.lineNumber()}: ${consoleMessage.message()}")
- return super.onConsoleMessage(consoleMessage)
+ return true
}
override fun onProgressChanged(view: WebView, newProgress: Int) {
diff --git a/app/src/main/res/drawable/frost_f_24.xml b/app/src/main/res/drawable/frost_f_24.xml
index b435fa032de..18271849db6 100644
--- a/app/src/main/res/drawable/frost_f_24.xml
+++ b/app/src/main/res/drawable/frost_f_24.xml
@@ -8,7 +8,7 @@
\ No newline at end of file
diff --git a/app/src/main/res/drawable/frost_f_256.xml b/app/src/main/res/drawable/frost_f_256.xml
index fce1b5caf17..220dee6963f 100644
--- a/app/src/main/res/drawable/frost_f_256.xml
+++ b/app/src/main/res/drawable/frost_f_256.xml
@@ -8,7 +8,7 @@
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_image.xml b/app/src/main/res/layout/activity_image.xml
new file mode 100644
index 00000000000..a2264b25364
--- /dev/null
+++ b/app/src/main/res/layout/activity_image.xml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_image_textless.xml b/app/src/main/res/layout/activity_image_textless.xml
new file mode 100644
index 00000000000..3c0cc6859fd
--- /dev/null
+++ b/app/src/main/res/layout/activity_image_textless.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml
index eef0e434b07..cd5eef081e7 100644
--- a/app/src/main/res/layout/activity_login.xml
+++ b/app/src/main/res/layout/activity_login.xml
@@ -6,7 +6,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
- tools:context=".LoginActivity">
+ tools:context=".activities.LoginActivity">
+ tools:context=".activities.MainActivity">
+ tools:context=".activities.WebOverlayActivity">
Frost Pro has been restored. Enjoy the features!
It seems like you don\'t have pro. If this is a persistent issue, contact me and attach your purchase receipt.
-
-
- Raizlabs
- https://www.raizlabs.com/
-
- DbFlow
-
- annotation processing.
-
- The library is built on speed, performance, and approachability. It not only eliminates most boiler-plate code for dealing with databases, but also provides a powerful and simple API to manage interactions.
- Let DBFlow make SQL code flow like a steady stream so you can focus on writing amazing apps.
- ]]>
-
- https://github.com/Raizlabs/DBFlow
- 4.0.4
-
- true
- https://github.com/Raizlabs/DBFlow
-
- com.raizlabs.android.dbflow
-
- mit
Login failed; id not found
IAB query is still in progress
New Message
+ No text
+ Image downloaded
+ Image failed to download
+ Failed to share image
diff --git a/app/src/main/res/values/strings_libs.xml b/app/src/main/res/values/strings_libs.xml
new file mode 100644
index 00000000000..9cbb77d7157
--- /dev/null
+++ b/app/src/main/res/values/strings_libs.xml
@@ -0,0 +1,26 @@
+
+
+
+
+ Raizlabs
+ https://www.raizlabs.com/
+
+ DbFlow
+
+ annotation processing.
+
+ The library is built on speed, performance, and approachability. It not only eliminates most boiler-plate code for dealing with databases, but also provides a powerful and simple API to manage interactions.
+ Let DBFlow make SQL code flow like a steady stream so you can focus on writing amazing apps.
+ ]]>
+
+ https://github.com/Raizlabs/DBFlow
+ 4.0.4
+
+ true
+ https://github.com/Raizlabs/DBFlow
+
+ com.raizlabs.android.dbflow
+
+ mit
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings_pref_experimental.xml b/app/src/main/res/values/strings_pref_experimental.xml
index 2d49864b151..0f545b3e0e9 100644
--- a/app/src/main/res/values/strings_pref_experimental.xml
+++ b/app/src/main/res/values/strings_pref_experimental.xml
@@ -11,5 +11,4 @@
Enable verbose logging to help with crash reports. Logging will only be sent once an error is encountered, so repeat the issue to notify the dev. This will automatically be disabled if the app restarts.
Restart Frost
Crashlytics will only submit logs when a crash occurs or if errors are found and the app is restarted. Clicking here will restart the app and flush whatever issues are currently found.
-
\ No newline at end of file
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 217bfb28c58..a483b5f0de3 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -31,9 +31,16 @@
+
+
+
+
diff --git a/app/src/main/res/xml/changelog.xml b/app/src/main/res/xml/changelog.xml
index 59baeef5ccd..cf56eaeb9ca 100644
--- a/app/src/main/res/xml/changelog.xml
+++ b/app/src/main/res/xml/changelog.xml
@@ -9,12 +9,13 @@
-->
-
-
-
-
-
-
+
+
+
+
+
+
+
@@ -25,6 +26,12 @@
+
+
+
+
+
+
diff --git a/app/src/main/res/xml/file_paths.xml b/app/src/main/res/xml/file_paths.xml
new file mode 100644
index 00000000000..334ea0d720b
--- /dev/null
+++ b/app/src/main/res/xml/file_paths.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/releaseTest/res/xml/file_paths.xml b/app/src/releaseTest/res/xml/file_paths.xml
new file mode 100644
index 00000000000..139a1972ec3
--- /dev/null
+++ b/app/src/releaseTest/res/xml/file_paths.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbUrlTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbUrlTest.kt
index d7ec4b46345..080132bdf3a 100644
--- a/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbUrlTest.kt
+++ b/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbUrlTest.kt
@@ -1,5 +1,6 @@
package com.pitchedapps.frost.facebook
+import okhttp3.HttpUrl
import org.junit.Test
import kotlin.test.assertEquals
@@ -9,6 +10,11 @@ import kotlin.test.assertEquals
*/
class FbUrlTest {
+ fun assertFbFormat(expected: String, url: String) {
+ val fbUrl = FbUrlFormatter(url)
+ assertEquals(expected, fbUrl.toString(), "FbUrl Mismatch:\n${fbUrl.toLogList().joinToString("\n\t")}")
+ }
+
@Test
fun base() {
val url = "https://touch.facebook.com/relative/?asdf=1234&hjkl=7890"
@@ -32,8 +38,10 @@ class FbUrlTest {
assertFbFormat("$prefix$suffix", "$prefix&ref=hello$suffix")
}
- fun assertFbFormat(expected: String, url: String) {
- val fbUrl = FbUrlFormatter(url)
- assertEquals(expected, fbUrl.toString(), "FbUrl Mismatch:\n${fbUrl.toLogList().joinToString("\n\t")}")
+ @Test fun css() {
+ val expected = "https://test.com?efg=hi&oh=bye&oe=apple"
+ val orig = "https\\3a //test.com?efg\\3d hi\\26 oh\\3d bye\\26 oe\\3d apple"
+ assertFbFormat(expected, orig)
}
+
}
\ No newline at end of file
diff --git a/docs/Changelog.md b/docs/Changelog.md
index f8d3308f502..79f7d6923c2 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -1,12 +1,8 @@
# Changelog
## Beta Updates
-* Reduce Menu loading logic
-* Load js injectors after showing webview
-* Add toggles for sound, vibration, and lights
-* Avoid restricting facebook features (such as user tagging)
-* Slightly decrease wait time before making webview visible
-* Add option to disable loading in overlays
+* Update IAB helper
+* Implemented image viewing and downloading; long press any image!
## v1.3
* Create toggle for notifications only from primary account
@@ -15,6 +11,12 @@
* Make notifications expandable
* Add notification trigger in settings
* Fix bug where only single latest notification is showing
+* Reduce Menu loading logic
+* Load js injectors after showing webview
+* Add toggles for sound, vibration, and lights
+* Avoid restricting facebook features (such as user tagging)
+* Add option to disable loading in overlays
+* Fixed experimental search result text
## v1.2
* Scale browser on keyboard pop up
diff --git a/gradle.properties b/gradle.properties
index 8dc22a8810b..7ac04b38510 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -17,16 +17,19 @@ MIN_SDK=21
TARGET_SDK=26
BUILD_TOOLS=26.0.0
-KAU=v2.0
+KAU=e6daff7
KOTLIN=1.1.3-2
-MATERIAL_DRAWER=5.9.4
-MATERIAL_DRAWER_KT=1.0.5
-IICON_MATERIAL=2.2.0.3
+CRASHLYTICS=2.6.8
+DBFLOW=4.0.4
+GLIDE=4.0.0-RC1
IICON_COMMUNITY=1.9.32.2
+IICON_MATERIAL=2.2.0.3
JSOUP=1.10.3
-GLIDE=4.0.0-RC1
-DBFLOW=4.0.4
-PAPER_PARCEL=2.0.1
-CRASHLYTICS=2.6.8
LEAK_CANARY=1.5.1
-ROBOELECTRIC=3.4-rc3
\ No newline at end of file
+MATERIAL_DRAWER=5.9.4
+MATERIAL_DRAWER_KT=1.0.5
+OKHTTP=3.8.1
+PAPER_PARCEL=2.0.1
+ROBOELECTRIC=3.4-rc3
+SCALE_IMAGE_VIEW=3.6.0
+SLIDING_PANEL=3.3.1
\ No newline at end of file