Skip to content
This repository has been archived by the owner on Nov 30, 2022. It is now read-only.

Commit

Permalink
Merge pull request #5 from 47deg/google-analytics
Browse files Browse the repository at this point in the history
Google Analytics and new sections in README
  • Loading branch information
Javi Pacheco committed Jan 20, 2015
2 parents b310b30 + 3288a06 commit 0417885
Show file tree
Hide file tree
Showing 14 changed files with 231 additions and 30 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Scala on Android
==============

This application is written entirely in Scala on Android. We are excited to make the application open source and share the code with you. We have used the [macroid](http://macroid.github.io/) library extensively in this project. In addition we have contributed our own Macroid extenions to this application, that can be found here: [macroid-extras](http://macroid.github.io/).

Compile
======

Expand All @@ -27,7 +28,8 @@ $ ./activator
> run
```

You can use your favorite IDE. At 47 Degrees we use IntelliJ with the Scala plugin. If you want to run this project from IntelliJ you only need to import the project.
You can use your favorite IDE. At 47 Degrees we use IntelliJ with the Scala plugin. If you want to run this project from IntelliJ you only need to import the project.

Download
========

Expand Down
13 changes: 11 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import Libraries.android._
import Libraries.macroid._
import Libraries.playServices._
import Libraries.json._
import android.PromptPasswordsSigningConfig

android.Plugin.androidBuild

Expand All @@ -27,14 +29,21 @@ resolvers ++= Settings.resolvers
libraryDependencies ++= Seq(
aar(macroidRoot),
aar(androidAppCompat),
aar(androidCardView),
aar(androidRecyclerview),
aar(macroidExtras),
aar(playServicesBase),
json4s,
compilerPlugin(Libraries.wartRemover))


apkSigningConfig in Android := Option(
PromptPasswordsSigningConfig(
keystore = new File(Path.userHome.absolutePath + "/.android/translate-bubble.keystore"),
alias = "47deg"))

run <<= run in Android

packageRelease <<= packageRelease in Android

proguardScala in Android := true

useProguard in Android := true
Expand Down
9 changes: 3 additions & 6 deletions proguard-sbt.txt
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,6 @@
# view res/layout/abc_search_view.xml #generated:78
-keep class android.support.v7.widget.SearchView$SearchAutoComplete { <init>(...); }

# view AndroidManifest.xml #generated:26
-keep class android.support.v7.widget.TestActivity { <init>(...); }

# view res/layout/abc_screen_toolbar.xml #generated:36
-keep class android.support.v7.widget.Toolbar { <init>(...); }

Expand All @@ -184,11 +181,11 @@
# view AndroidManifest.xml #generated:16
-keep class com.fortysevendeg.translatebubble.ui.bubbleservice.BubbleService { <init>(...); }

# view res/layout/actions_view.xml #generated:21
# view res/layout/actions_view.xml #generated:37
-keep class com.fortysevendeg.translatebubble.ui.components.CloseView { <init>(...); }

# view res/layout/actions_view.xml #generated:11
# view res/layout/actions_view.xml #generated:15
# view res/layout/actions_view.xml #generated:27
# view res/layout/actions_view.xml #generated:31
-keep class com.fortysevendeg.translatebubble.ui.components.DisableView { <init>(...); }

# view AndroidManifest.xml #generated:14
Expand Down
21 changes: 21 additions & 0 deletions project/Libraries.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,27 @@ object Libraries {
lazy val androidCardView = androidDep("cardview-v7")
}

object playServices {

def playServicesDep(module: String) = "com.google.android.gms" % module % Versions.playServicesV

lazy val playServicesGooglePlus = playServicesDep("play-services-plus")
lazy val playServicesAccountLogin = playServicesDep("play-services-identity")
lazy val playServicesActivityRecognition = playServicesDep("play-services-location")
lazy val playServicesAppIndexing = playServicesDep("play-services-appindexing")
lazy val playServicesCast = playServicesDep("play-services-cast")
lazy val playServicesDrive = playServicesDep("play-services-drive")
lazy val playServicesFit = playServicesDep("play-services-fitness")
lazy val playServicesMaps = playServicesDep("play-services-maps")
lazy val playServicesAds = playServicesDep("play-services-ads")
lazy val playServicesPanoramaViewer = playServicesDep("play-services-panorama")
lazy val playServicesGames = playServicesDep("play-services-games")
lazy val playServicesWallet = playServicesDep("play-services-wallet")
lazy val playServicesWear = playServicesDep("play-services-wearable")
// Google Actions, Google Analytics and Google Cloud Messaging
lazy val playServicesBase = playServicesDep("play-services-base")
}

object macroid {

def macroid(module: String = "") =
Expand Down
1 change: 1 addition & 0 deletions project/Versions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ object Versions {
val macroidV = "2.0.0-M3"
val wartremoverV = "0.11"
val json4s = "3.2.10"
val playServicesV = "6.5.87"
}
26 changes: 26 additions & 0 deletions src/main/res/xml/app_tracker.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2015 47 Degrees, LLC http://47deg.com hello@47deg.com
~
~ Licensed under the Apache License, Version 2.0 (the "License"); you may
~ not use this file except in compliance with the License. You may obtain
~ a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->

<resources>

<string name="ga_appName">Translate Bubble</string>

<bool name="ga_autoActivityTracking">false</bool>

<string name="ga_trackingId">UA-58651614-1</string>

</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.fortysevendeg.translatebubble.modules

import com.fortysevendeg.translatebubble.modules.analytics.AnalyticsServicesComponent
import com.fortysevendeg.translatebubble.modules.clipboard.{ClipboardServicesComponent, ClipboardServices}
import com.fortysevendeg.translatebubble.modules.notifications.{NotificationsServicesComponent, NotificationsServices}
import com.fortysevendeg.translatebubble.modules.persistent.{PersistentServicesComponent, PersistentServices}
Expand All @@ -26,3 +27,4 @@ trait ComponentRegistry
with PersistentServicesComponent
with TranslateServicesComponent
with NotificationsServicesComponent
with AnalyticsServicesComponent
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.fortysevendeg.translatebubble.modules

import com.fortysevendeg.macroid.extras.AppContextProvider
import com.fortysevendeg.translatebubble.modules.analytics.impl.AnalyticsServicesComponentImpl
import com.fortysevendeg.translatebubble.modules.clipboard.impl.ClipboardServicesComponentImpl
import com.fortysevendeg.translatebubble.modules.notifications.impl.NotificationsServicesComponentImpl
import com.fortysevendeg.translatebubble.modules.persistent.impl.PersistentServicesComponentImpl
Expand All @@ -29,3 +30,4 @@ trait ComponentRegistryImpl
with PersistentServicesComponentImpl
with TranslateServicesComponentImpl
with NotificationsServicesComponentImpl
with AnalyticsServicesComponentImpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright (C) 2015 47 Degrees, LLC http://47deg.com hello@47deg.com
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.fortysevendeg.translatebubble.modules.analytics

trait AnalyticsServices {
def send(screenName: String,
category: Option[String] = None,
action: Option[String] = None,
label: Option[String] = None): Unit
}

trait AnalyticsServicesComponent {
val analyticsServices: AnalyticsServices
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright (C) 2015 47 Degrees, LLC http://47deg.com hello@47deg.com
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.fortysevendeg.translatebubble.modules.analytics.impl

import com.fortysevendeg.macroid.extras.AppContextProvider
import com.fortysevendeg.translatebubble.R
import com.fortysevendeg.translatebubble.modules.analytics.{AnalyticsServices, AnalyticsServicesComponent}
import com.google.android.gms.analytics.{HitBuilders, GoogleAnalytics}

trait AnalyticsServicesComponentImpl
extends AnalyticsServicesComponent {

self: AppContextProvider =>

lazy val analyticsServices = new AnalyticsServicesImpl

class AnalyticsServicesImpl
extends AnalyticsServices {

lazy val tracker = {
val googleAnalytics = GoogleAnalytics.getInstance(appContextProvider.get)
googleAnalytics.newTracker(R.xml.app_tracker)
}

def send(screenName: String,
category: Option[String] = None,
action: Option[String] = None,
label: Option[String] = None): Unit = {
tracker.setScreenName(screenName)
val event = new HitBuilders.EventBuilder()
category map (event.setCategory(_))
action map (event.setAction(_))
label map (event.setLabel(_))
tracker.send(event.build())
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import com.fortysevendeg.translatebubble.ui.components.{ActionsView, BubbleView,
import com.fortysevendeg.translatebubble.utils.TranslateUIType
import macroid.FullDsl._
import macroid.{AppContext, Ui}
import com.fortysevendeg.translatebubble.ui.commons.Strings._

import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{Failure, Try}
Expand Down Expand Up @@ -99,10 +100,16 @@ class BubbleService
bubble.hideFromCloseAction(paramsBubble, windowManager)
// Bubble was moved over DisableTranslation
case actionsView if (actionsView.isOverDisableView(x, y)) =>
analyticsServices.send(
analyticsTranslateService,
Some(analyticsDisable))
persistentServices.disableTranslation()
bubble.hideFromOptionAction(paramsBubble, windowManager)
// Bubble was moved over DisableTranslation during 30 minutes
case actionsView if (actionsView.isOver30minView(x, y)) =>
analyticsServices.send(
analyticsTranslateService,
Some(analytics30MinDisable))
persistentServices.disable30MinutesTranslation()
bubble.hideFromOptionAction(paramsBubble, windowManager)
// Bubble drops somewhere else
Expand Down Expand Up @@ -355,11 +362,8 @@ class BubbleService
private def onStartTranslate() {
val typeTranslateUI = persistentServices.getTypeTranslateUI()
if (typeTranslateUI == TranslateUIType.BUBBLE) {
if (bubbleStatus == BubbleStatus.FLOATING) {
bubble.show(paramsBubble, windowManager)
} else {
contentView.setTexts(getString(R.string.translating), "", "")
}
bubble.show(paramsBubble, windowManager)
contentView.setTexts(getString(R.string.translating), "", "")
}

val result = for {
Expand All @@ -368,40 +372,49 @@ class BubbleService
translateResponse <- translateServices.translate(
TranslateRequest(text = textResponse.text, from = persistentResponse.from, to = persistentResponse.to)
)
} yield (textResponse.text, translateResponse.translated)
result.mapUi(texts => onEndTranslate(texts._1, texts._2)).recover {
} yield (textResponse.text, translateResponse.translated,
"%s-%s".format(persistentResponse.from.toString, persistentResponse.to.toString))
result.mapUi(texts => onEndTranslate(texts._1, texts._2, texts._3)).recover {
case _ => translatedFailed()
}

}

private def onEndTranslate(maybeOriginalText: Option[String], maybeTranslatedText: Option[String]) = {
private def onEndTranslate(
maybeOriginalText: Option[String],
maybeTranslatedText: Option[String],
label: String) = {
val typeTranslateUI = persistentServices.getTypeTranslateUI()

analyticsServices.send(
analyticsTranslateService,
Some(typeTranslateUI.toString),
Some(analyticsClipboard),
Some(label))

for {
originalText <- maybeOriginalText
translatedText <- maybeTranslatedText
languages <- persistentServices.getLanguagesString
} yield {
if (typeTranslateUI == TranslateUIType.BUBBLE) {
contentView.setTexts(languages, originalText, translatedText)
if (bubbleStatus == BubbleStatus.FLOATING) {
typeTranslateUI match {
case TranslateUIType.BUBBLE =>
contentView.setTexts(languages, originalText, translatedText)
bubble.stopAnimation()
}
} else if (typeTranslateUI == TranslateUIType.NOTIFICATION) {
notificationsServices.showTextTranslated(ShowTextTranslatedRequest(originalText, translatedText))
case TranslateUIType.NOTIFICATION =>
notificationsServices.showTextTranslated(ShowTextTranslatedRequest(originalText, translatedText))
}
}
}

private def translatedFailed() {
val typeTranslateUI = persistentServices.getTypeTranslateUI()
if (typeTranslateUI == TranslateUIType.BUBBLE) {
contentView.setTexts(getString(R.string.failedTitle), getString(R.string.failedMessage), "")
if (bubbleStatus == BubbleStatus.FLOATING) {
typeTranslateUI match {
case TranslateUIType.BUBBLE =>
contentView.setTexts(getString(R.string.failedTitle), getString(R.string.failedMessage), "")
bubble.stopAnimation()
}
} else if (typeTranslateUI == TranslateUIType.NOTIFICATION) {
notificationsServices.failed()
case TranslateUIType.NOTIFICATION =>
notificationsServices.failed()
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright (C) 2015 47 Degrees, LLC http://47deg.com hello@47deg.com
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.fortysevendeg.translatebubble.ui.commons

object Strings {

val analyticsPreferencesScreen = "Preferences Screen"

val analyticsWizardScreen = "Wizard Screen"

val analyticsOpenSourceDialog = "Open Source Dialog"

val analyticsGoToGitHub = "Go To GitHub"

val analyticsTutorialScreen = "Tutorial Screen"

val analyticsTranslateService = "Translate Service"

val analyticsClipboard = "Clipboard"

val analyticsDisable = "Disable from Bubble"

val analytics30MinDisable = "Disable 30 minutes from Bubble"

}

0 comments on commit 0417885

Please sign in to comment.