From d90cb9b61cd2e033b46f4780ad1340c5f35b7751 Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Sun, 16 Jul 2017 17:26:58 -0700 Subject: [PATCH] Add image viewing and downloading (#63) * Commence aggressive image caching * Add glide toggle and css url parsing * Add image hook and refractor activities * Update version analytics * Implemented imageactivity but glide will not load * Create working image loader * Finalize image view * Finalize image view logic * Remove custom cache experiment --- app/build.gradle | 6 + app/src/debug/res/xml/file_paths.xml | 9 + app/src/main/AndroidManifest.xml | 30 +- app/src/main/assets/adblock.txt | 2344 +++++++++++++++++ app/src/main/assets/js/click_a.js | 2 +- app/src/main/assets/js/click_a.min.js | 4 +- app/src/main/assets/js/context_a.js | 20 +- app/src/main/assets/js/context_a.min.js | 32 +- .../kotlin/com/pitchedapps/frost/FrostApp.kt | 1 + .../com/pitchedapps/frost/StartActivity.kt | 3 + .../frost/{ => activities}/AboutActivity.kt | 4 +- .../frost/{ => activities}/BaseActivity.kt | 3 +- .../{ => activities}/FrostWebActivity.kt | 2 +- .../frost/activities/ImageActivity.kt | 297 +++ .../frost/{ => activities}/LoginActivity.kt | 3 +- .../frost/{ => activities}/MainActivity.kt | 14 +- .../{ => activities}/SelectorActivity.kt | 3 +- .../{ => activities}/SettingsActivity.kt | 4 +- .../{ => activities}/WebOverlayActivity.kt | 3 +- .../com/pitchedapps/frost/facebook/FbConst.kt | 2 +- .../frost/facebook/FbUrlFormatter.kt | 16 +- .../frost/fragments/WebFragment.kt | 2 +- .../frost/services/FrostNotifications.kt | 2 +- .../pitchedapps/frost/settings/Appearance.kt | 4 +- .../pitchedapps/frost/settings/Behaviour.kt | 4 +- .../frost/settings/Experimental.kt | 8 +- .../com/pitchedapps/frost/settings/Feed.kt | 4 +- .../frost/settings/Notifications.kt | 2 +- .../com/pitchedapps/frost/utils/Prefs.kt | 16 + .../com/pitchedapps/frost/utils/Utils.kt | 21 +- .../pitchedapps/frost/utils/WebContextMenu.kt | 12 +- .../com/pitchedapps/frost/utils/iab/IAB.kt | 2 +- .../pitchedapps/frost/utils/iab/IABDialogs.kt | 4 +- .../frost/web/BaseWebViewClient.kt | 16 + .../frost/web/FrostChromeClient.kt | 16 +- .../com/pitchedapps/frost/web/FrostJSI.kt | 31 +- .../frost/web/FrostRequestInterceptor.kt | 67 + .../com/pitchedapps/frost/web/FrostWebView.kt | 2 +- .../frost/web/FrostWebViewClient.kt | 21 +- .../pitchedapps/frost/web/FrostWebViewCore.kt | 13 +- .../frost/web/FrostWebViewSearch.kt | 18 +- .../com/pitchedapps/frost/web/LoginWebView.kt | 4 +- app/src/main/res/drawable/frost_f_24.xml | 2 +- app/src/main/res/drawable/frost_f_256.xml | 2 +- app/src/main/res/layout/activity_image.xml | 48 + .../res/layout/activity_image_textless.xml | 30 + app/src/main/res/layout/activity_login.xml | 2 +- app/src/main/res/layout/activity_main.xml | 2 +- .../main/res/layout/activity_web_overlay.xml | 2 +- app/src/main/res/values/strings.xml | 27 +- app/src/main/res/values/strings_libs.xml | 26 + .../res/values/strings_pref_experimental.xml | 1 - app/src/main/res/values/styles.xml | 7 + app/src/main/res/xml/changelog.xml | 19 +- app/src/main/res/xml/file_paths.xml | 9 + app/src/releaseTest/res/xml/file_paths.xml | 9 + .../pitchedapps/frost/facebook/FbUrlTest.kt | 14 +- docs/Changelog.md | 14 +- gradle.properties | 21 +- 59 files changed, 3148 insertions(+), 158 deletions(-) create mode 100644 app/src/debug/res/xml/file_paths.xml create mode 100644 app/src/main/assets/adblock.txt rename app/src/main/kotlin/com/pitchedapps/frost/{ => activities}/AboutActivity.kt (98%) rename app/src/main/kotlin/com/pitchedapps/frost/{ => activities}/BaseActivity.kt (93%) rename app/src/main/kotlin/com/pitchedapps/frost/{ => activities}/FrostWebActivity.kt (92%) create mode 100644 app/src/main/kotlin/com/pitchedapps/frost/activities/ImageActivity.kt rename app/src/main/kotlin/com/pitchedapps/frost/{ => activities}/LoginActivity.kt (98%) rename app/src/main/kotlin/com/pitchedapps/frost/{ => activities}/MainActivity.kt (97%) rename app/src/main/kotlin/com/pitchedapps/frost/{ => activities}/SelectorActivity.kt (96%) rename app/src/main/kotlin/com/pitchedapps/frost/{ => activities}/SettingsActivity.kt (97%) rename app/src/main/kotlin/com/pitchedapps/frost/{ => activities}/WebOverlayActivity.kt (98%) create mode 100644 app/src/main/kotlin/com/pitchedapps/frost/web/BaseWebViewClient.kt create mode 100644 app/src/main/kotlin/com/pitchedapps/frost/web/FrostRequestInterceptor.kt create mode 100644 app/src/main/res/layout/activity_image.xml create mode 100644 app/src/main/res/layout/activity_image_textless.xml create mode 100644 app/src/main/res/values/strings_libs.xml create mode 100644 app/src/main/res/xml/file_paths.xml create mode 100644 app/src/releaseTest/res/xml/file_paths.xml 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