Setup
Install and setup Android Studio as described in the following link.
Unzip "main_files.zip", and follow the documentation on how to import the project.
After what the project was imported, find "secrets.properties" file under the root directory and open it.
And change all values to your own, don't use default added values:
base_url=https://api.openai.com
openai_key=ADD_YOUR_OWN_KEY
privacy_policy_url=ADD_YOUR_PRIVACY_POLICY_URL
terms_and_conditions=ADD_YOUR_TERMS_AND_CONDITIONS_URL
iap_remove_ads=ADD_YOUR_PRODUCT_ID_FROM_GOOGLE_PLAY_CONSOLE
iap_price=0.99$
interstitial_ad_frequency=3
rewarded_ad_frequency=2
show_interstitial_ads=true
show_rewarded_ads=true
base_url - This is the openAi base url used for generating emails. Don't change it until it is update by OpenAi.
openai_key - Generate your own token here: https://platform.openai.com/account/api-keys
show_interstitial_ads - If set to false it will not show the Interstitial ad
interstitial_ad_frequency - Set the frequency for showing Interstitial ad. Interstitial ad is showing after user navigates to different screen. If the number of times user navigated to other screen is equal to interstitial_ad_frequency then the ad will be shown and counter will be reseted.
show_rewarded_ads - If set to false it will not show the Rewarded ad
rewarded_ad_frequency - Set the frequency for showing Rewarded ad. Rewarded ad is showing after user navigates to different screen. If the number of times user navigated to other screen is equal to rewarded_ad_frequency then the ad will be shown and counter will be reseted.
terms_and_conditions - Update your terms url. User can see your terms and conditions page from the settings screen of the app.
privacy_policy_url - Update your privacy url. User can see your privacy policy page from the settings screen of the app.
iap_remove_ads - Change your In-app product id from the Google Play Console. This In-app product corresponds to the Remove ads option.
iap_price - Set the price for removing ads product (the same as is set in Google play console when created a product id in InApp purchase section). This info will be shown on settings screen
Find key.properties and add your information about keystore. It is needed for signing release version of the app. More detailed info on how to sign Android app can be found here.
storeFile= #path to keystore
storePassword= #add your password
keyAlias= # add your key alias
keyPassword=#add your key password
Ads
Free version of the app shows Ad banner, as well as Interstitial ad. In order to add your own ad ids, you need to have an AdMob account, then update ad ids inside ads.xml with yours.(ads.xml can be found in the next project path: /app/src/res/values/ads.xml)
ad_app_id corresponds to your AdMob App ID
banner_ad_unit_id corresponds to your banner ad unit id
interstitial_ad_unit_id corresponds to your interstitial ad unit id
rewarded_ad_unit_id corresponds to your rewarded ad unit id
If you need more control on showing ads you can check AdsManager.kt class.
"AdsManager.kt" class is responsible for loading and showing ads.
showInterstitialAd(activity: Activity) /// Show interstitial ad.
fun showRewardedAd(activity: Activity, callback: (RewardItem) -> Unit) /// Show rewarded ad. You will receive RewardItem in lambda and do whatever you want with the info received about RewardItem.
You can inject "AdsManager.kt" class in any screen you want using below line of code. Note: Koin is used for dependency injection
private val adsManager: AdsManager by inject()
And then use adsManager to show the ads. Below you can find example of codes from the project how it is done:
// Show Interstitial Ad.
adsManager.showInterstitialAd(this)
// Show rewarded Ad. Note that last argument is a lambda that will execute after what the reward was received after watching entire Ad.
adsManager.showRewardedAd(this) {
// You can do whatever you want in this lambda.
}
Change package name and replace Firebase google-services.json file
Here you can find a video recording how to change the package name for the project, also how to replace Firebase google-services.json file.
Architecture
More information about app architecture can be found by folowing this link.
The UI is built using Jetpack compose.
Splash Screen
"SplashFragment" class, is the entry point of the app on which it checks if InApp product was purchased and saves to preferences if it was purchased or not in order to show ads to the user.
In general all screens in the app are composed from 3 components (Fragment, Screen and ViewModel). Thus in this case for the Splash page you will find SplashFragment.kt, SplashScreen.kt and SplashViewModel.kt classes. The same pattern is applied for the rest of the application screens. The fragment holds the page, screen is the UI representation of the page, and viewmodel holds the logic of the page.
EmailGenerator Screen
"EmailGeneratorFragment" class, is the main page of the app. Here you can select a tone, select the email length and add additional description. Once the description will be set the Generate button will be eneabled. By clicking on the button next method will be invoked:
onGenerateEmailClick = { fromName, toName, description ->
emailGeneratorViewModel.generateEmail(fromName, toName, description)
}
And the later will call the "generateEmail(prompt: String)" method from "OpenAiRepository" class:
service.generateEmail(
CompletionRequest(
model = "text-davinci-003",
maxTokens = 100,
temperature = 0.4f,
prompt = prompt
)
)
model - AI model used for email generation. You can use one of : "text-davinci-003", "text-curie-001", "text-babbage-001", "text-ada-001". "text-davinci-003" is the most advanced one.
maxTokens - The maximum number of tokens to generate in the completion. The token count of your prompt plus maxTokens cannot exceed the model's context length. Most models have a context length of 2048 tokens.
temperature - What sampling temperature to use, between 0 and 2. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic.
Result Screen
"EmailResultFragment" class, presents the result received from EmailGeneratorFragment after the enabled generate button is pressed.
onRegenerateEmailClick = {
emailResultViewModel.regenerateEmail(args.prompt)
}
This method is called when the regenerate button is tapped. Which will call the same "generateEmail(prompt: String)" method from "OpenAiRepository" class that was described on EmailGenerator screen.
Settings Screen
"SettingsFragment" class, shows the app settings or other things related to the app. Things like remove ads, terms and conditions, privacy colicy, about.
Check the SettingsViewModel and SettingsScreen for more information.
IAP
The app has included In app Purchase manager which uses API.
IapManager contains all workaround IAP needed.
Saving value when user has successfully become a pro:
Persistance (DataStorePreferences):
dataStorePreferences.setBooleanPreferences(
DataStorePreferencesImpl.isPremiumPurchased,
purchasedPremium != null
)
Purchasing remove ads item:
IapManager:
fun purchasePremium(activity: Activity)
Reskin
For updating app colors go to /ui/theme/colors/ folder and update both files "MailGenLightColorPalette" and "MailGenDarkColorPalette" that corresponds for light and dark theme correspondingly.
App colors that can be updated can be found below:
pageBackground = Black700,
cardBackground = Black500,
splashBackground = Black500,
surfaceBackground = Black100,
primaryText = White,
secondaryText = White200,
tertiaryText = White300,
selectedChipText = White,
primaryButton = Blue500,
itemSelectedBg = Blue500,
itemUnselectedBg = Green700.copy(alpha = 0.69f),
success = Green300,
error = Red300,
Texts in app can be updated from the strings.xml file.