Add donation options to settings
This commit is contained in:
parent
09d68ec197
commit
4e2e3fb4e2
|
@ -13,7 +13,7 @@ android {
|
||||||
applicationId "org.joinmastodon.android"
|
applicationId "org.joinmastodon.android"
|
||||||
minSdk 23
|
minSdk 23
|
||||||
targetSdk 33
|
targetSdk 33
|
||||||
versionCode 103
|
versionCode 104
|
||||||
versionName "2.5.2"
|
versionName "2.5.2"
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,20 @@
|
||||||
package org.joinmastodon.android.api.requests.catalog;
|
package org.joinmastodon.android.api.requests.catalog;
|
||||||
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import org.joinmastodon.android.model.donations.DonationCampaign;
|
import org.joinmastodon.android.model.donations.DonationCampaign;
|
||||||
|
|
||||||
public class GetDonationCampaigns extends MastodonAPIRequest<DonationCampaign>{
|
public class GetDonationCampaigns extends MastodonAPIRequest<DonationCampaign>{
|
||||||
private final String locale, seed;
|
private final String locale, seed, source;
|
||||||
private boolean staging;
|
private boolean staging;
|
||||||
|
|
||||||
public GetDonationCampaigns(String locale, String seed){
|
public GetDonationCampaigns(String locale, String seed, String source){
|
||||||
super(HttpMethod.GET, null, DonationCampaign.class);
|
super(HttpMethod.GET, null, DonationCampaign.class);
|
||||||
this.locale=locale;
|
this.locale=locale;
|
||||||
this.seed=seed;
|
this.seed=seed;
|
||||||
|
this.source=source;
|
||||||
setCacheable();
|
setCacheable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +33,8 @@ public class GetDonationCampaigns extends MastodonAPIRequest<DonationCampaign>{
|
||||||
.appendQueryParameter("seed", seed);
|
.appendQueryParameter("seed", seed);
|
||||||
if(staging)
|
if(staging)
|
||||||
builder.appendQueryParameter("environment", "staging");
|
builder.appendQueryParameter("environment", "staging");
|
||||||
|
if(!TextUtils.isEmpty(source))
|
||||||
|
builder.appendQueryParameter("source", source);
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,9 +116,8 @@ public class HomeTimelineFragment extends StatusListFragment implements ToolbarD
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
localTimelineBannerHelper=new DiscoverInfoBannerHelper(DiscoverInfoBannerHelper.BannerType.LOCAL_TIMELINE, accountID);
|
localTimelineBannerHelper=new DiscoverInfoBannerHelper(DiscoverInfoBannerHelper.BannerType.LOCAL_TIMELINE, accountID);
|
||||||
|
|
||||||
// TODO how often do we do this request? Maybe cache something somewhere?
|
|
||||||
if(AccountSessionManager.get(accountID).isEligibleForDonations()){
|
if(AccountSessionManager.get(accountID).isEligibleForDonations()){
|
||||||
GetDonationCampaigns req=new GetDonationCampaigns(Locale.getDefault().toLanguageTag().replace('-', '_'), String.valueOf(AccountSessionManager.get(accountID).getDonationSeed()));
|
GetDonationCampaigns req=new GetDonationCampaigns(Locale.getDefault().toLanguageTag().replace('-', '_'), String.valueOf(AccountSessionManager.get(accountID).getDonationSeed()), null);
|
||||||
if(BuildConfig.DEBUG && getActivity().getSharedPreferences("debug", Context.MODE_PRIVATE).getBoolean("donationsStaging", false)){
|
if(BuildConfig.DEBUG && getActivity().getSharedPreferences("debug", Context.MODE_PRIVATE).getBoolean("donationsStaging", false)){
|
||||||
req.setStaging(true);
|
req.setStaging(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
package org.joinmastodon.android.fragments.settings;
|
package org.joinmastodon.android.fragments.settings;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.squareup.otto.Subscribe;
|
import com.squareup.otto.Subscribe;
|
||||||
|
|
||||||
|
@ -12,27 +16,38 @@ import org.joinmastodon.android.BuildConfig;
|
||||||
import org.joinmastodon.android.E;
|
import org.joinmastodon.android.E;
|
||||||
import org.joinmastodon.android.MainActivity;
|
import org.joinmastodon.android.MainActivity;
|
||||||
import org.joinmastodon.android.R;
|
import org.joinmastodon.android.R;
|
||||||
|
import org.joinmastodon.android.api.requests.catalog.GetDonationCampaigns;
|
||||||
import org.joinmastodon.android.api.session.AccountSession;
|
import org.joinmastodon.android.api.session.AccountSession;
|
||||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||||
import org.joinmastodon.android.events.SelfUpdateStateChangedEvent;
|
import org.joinmastodon.android.events.SelfUpdateStateChangedEvent;
|
||||||
|
import org.joinmastodon.android.model.donations.DonationCampaign;
|
||||||
import org.joinmastodon.android.model.viewmodel.ListItem;
|
import org.joinmastodon.android.model.viewmodel.ListItem;
|
||||||
import org.joinmastodon.android.ui.sheets.AccountSwitcherSheet;
|
|
||||||
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
|
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
|
||||||
|
import org.joinmastodon.android.ui.sheets.AccountSwitcherSheet;
|
||||||
|
import org.joinmastodon.android.ui.sheets.DonationSheet;
|
||||||
|
import org.joinmastodon.android.ui.sheets.DonationSuccessfulSheet;
|
||||||
import org.joinmastodon.android.ui.utils.HideableSingleViewRecyclerAdapter;
|
import org.joinmastodon.android.ui.utils.HideableSingleViewRecyclerAdapter;
|
||||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||||
import org.joinmastodon.android.updater.GithubSelfUpdater;
|
import org.joinmastodon.android.updater.GithubSelfUpdater;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
import me.grishka.appkit.Nav;
|
import me.grishka.appkit.Nav;
|
||||||
|
import me.grishka.appkit.api.Callback;
|
||||||
|
import me.grishka.appkit.api.ErrorResponse;
|
||||||
import me.grishka.appkit.utils.MergeRecyclerAdapter;
|
import me.grishka.appkit.utils.MergeRecyclerAdapter;
|
||||||
|
|
||||||
public class SettingsMainFragment extends BaseSettingsFragment<Void>{
|
public class SettingsMainFragment extends BaseSettingsFragment<Void>{
|
||||||
|
private static final int DONATION_RESULT=433;
|
||||||
|
|
||||||
private boolean loggedOut;
|
private boolean loggedOut;
|
||||||
private HideableSingleViewRecyclerAdapter bannerAdapter;
|
private HideableSingleViewRecyclerAdapter bannerAdapter;
|
||||||
private Button updateButton1, updateButton2;
|
private Button updateButton1, updateButton2;
|
||||||
private TextView updateText;
|
private TextView updateText;
|
||||||
|
private DonationSheet donationSheet;
|
||||||
private Runnable updateDownloadProgressUpdater=new Runnable(){
|
private Runnable updateDownloadProgressUpdater=new Runnable(){
|
||||||
@Override
|
@Override
|
||||||
public void run(){
|
public void run(){
|
||||||
|
@ -49,21 +64,26 @@ public class SettingsMainFragment extends BaseSettingsFragment<Void>{
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setTitle(R.string.settings);
|
setTitle(R.string.settings);
|
||||||
setSubtitle(AccountSessionManager.get(accountID).getFullUsername());
|
setSubtitle(AccountSessionManager.get(accountID).getFullUsername());
|
||||||
onDataLoaded(List.of(
|
ArrayList<ListItem<Void>> items=new ArrayList<>();
|
||||||
|
if(BuildConfig.DEBUG || BuildConfig.BUILD_TYPE.equals("appcenterPrivateBeta")){
|
||||||
|
items.add(new ListItem<>("Debug settings", null, R.drawable.ic_settings_24px, i->Nav.go(getActivity(), SettingsDebugFragment.class, makeFragmentArgs()), null, 0, true));
|
||||||
|
}
|
||||||
|
items.addAll(List.of(
|
||||||
new ListItem<>(R.string.settings_behavior, 0, R.drawable.ic_settings_24px, this::onBehaviorClick),
|
new ListItem<>(R.string.settings_behavior, 0, R.drawable.ic_settings_24px, this::onBehaviorClick),
|
||||||
new ListItem<>(R.string.settings_display, 0, R.drawable.ic_style_24px, this::onDisplayClick),
|
new ListItem<>(R.string.settings_display, 0, R.drawable.ic_style_24px, this::onDisplayClick),
|
||||||
new ListItem<>(R.string.settings_privacy, 0, R.drawable.ic_privacy_tip_24px, this::onPrivacyClick),
|
new ListItem<>(R.string.settings_privacy, 0, R.drawable.ic_privacy_tip_24px, this::onPrivacyClick),
|
||||||
new ListItem<>(R.string.settings_filters, 0, R.drawable.ic_filter_alt_24px, this::onFiltersClick),
|
new ListItem<>(R.string.settings_filters, 0, R.drawable.ic_filter_alt_24px, this::onFiltersClick),
|
||||||
new ListItem<>(R.string.settings_notifications, 0, R.drawable.ic_notifications_24px, this::onNotificationsClick),
|
new ListItem<>(R.string.settings_notifications, 0, R.drawable.ic_notifications_24px, this::onNotificationsClick),
|
||||||
new ListItem<>(AccountSessionManager.get(accountID).domain, getString(R.string.settings_server_explanation), R.drawable.ic_dns_24px, this::onServerClick),
|
new ListItem<>(AccountSessionManager.get(accountID).domain, getString(R.string.settings_server_explanation), R.drawable.ic_dns_24px, this::onServerClick),
|
||||||
new ListItem<>(getString(R.string.about_app, getString(R.string.app_name)), null, R.drawable.ic_info_24px, this::onAboutClick, null, 0, true),
|
new ListItem<>(getString(R.string.about_app, getString(R.string.app_name)), null, R.drawable.ic_info_24px, this::onAboutClick, null, 0, true)
|
||||||
new ListItem<>(R.string.manage_accounts, 0, R.drawable.ic_switch_account_24px, this::onManageAccountsClick),
|
|
||||||
new ListItem<>(R.string.log_out, 0, R.drawable.ic_logout_24px, this::onLogOutClick, R.attr.colorM3Error, false)
|
|
||||||
));
|
));
|
||||||
|
if(AccountSessionManager.get(accountID).isEligibleForDonations()){
|
||||||
if(BuildConfig.DEBUG || BuildConfig.BUILD_TYPE.equals("appcenterPrivateBeta")){
|
items.add(new ListItem<>(R.string.settings_donate, 0, R.drawable.ic_volunteer_activism_24px, this::onDonateClick));
|
||||||
data.add(0, new ListItem<>("Debug settings", null, R.drawable.ic_settings_24px, i->Nav.go(getActivity(), SettingsDebugFragment.class, makeFragmentArgs()), null, 0, true));
|
items.add(new ListItem<>(R.string.settings_manage_donations, 0, R.drawable.ic_settings_heart_24px, this::onManageDonationClick, 0, true));
|
||||||
}
|
}
|
||||||
|
items.add(new ListItem<>(R.string.manage_accounts, 0, R.drawable.ic_switch_account_24px, this::onManageAccountsClick));
|
||||||
|
items.add(new ListItem<>(R.string.log_out, 0, R.drawable.ic_logout_24px, this::onLogOutClick, R.attr.colorM3Error, false));
|
||||||
|
onDataLoaded(items);
|
||||||
|
|
||||||
AccountSession session=AccountSessionManager.get(accountID);
|
AccountSession session=AccountSessionManager.get(accountID);
|
||||||
session.reloadPreferences(null);
|
session.reloadPreferences(null);
|
||||||
|
@ -117,6 +137,17 @@ public class SettingsMainFragment extends BaseSettingsFragment<Void>{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onActivityResult(int requestCode, int resultCode, Intent data){
|
||||||
|
if(requestCode==DONATION_RESULT){
|
||||||
|
if(donationSheet!=null)
|
||||||
|
donationSheet.dismissWithoutAnimation();
|
||||||
|
if(resultCode==Activity.RESULT_OK){
|
||||||
|
new DonationSuccessfulSheet(getActivity(), accountID, data.getStringExtra("postText")).showWithoutAnimation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Bundle makeFragmentArgs(){
|
private Bundle makeFragmentArgs(){
|
||||||
Bundle args=new Bundle();
|
Bundle args=new Bundle();
|
||||||
args.putString("account", accountID);
|
args.putString("account", accountID);
|
||||||
|
@ -167,6 +198,39 @@ public class SettingsMainFragment extends BaseSettingsFragment<Void>{
|
||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onDonateClick(ListItem<?> item){
|
||||||
|
GetDonationCampaigns req=new GetDonationCampaigns(Locale.getDefault().toLanguageTag().replace('-', '_'), String.valueOf(AccountSessionManager.get(accountID).getDonationSeed()), null);
|
||||||
|
if(BuildConfig.DEBUG && getActivity().getSharedPreferences("debug", Context.MODE_PRIVATE).getBoolean("donationsStaging", false)){
|
||||||
|
req.setStaging(true);
|
||||||
|
}
|
||||||
|
req.setCallback(new Callback<>(){
|
||||||
|
@Override
|
||||||
|
public void onSuccess(DonationCampaign result){
|
||||||
|
Activity activity=getActivity();
|
||||||
|
if(activity==null)
|
||||||
|
return;
|
||||||
|
if(result==null){
|
||||||
|
Toast.makeText(activity, "No campaign available (server misconfiguration?)", Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
donationSheet=new DonationSheet(getActivity(), result, accountID, intent->startActivityForResult(intent, DONATION_RESULT));
|
||||||
|
donationSheet.setOnDismissListener(dialog->donationSheet=null);
|
||||||
|
donationSheet.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(ErrorResponse error){
|
||||||
|
error.showToast(getActivity());
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.wrapProgress(getActivity(), R.string.loading, true)
|
||||||
|
.execNoAuth("");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onManageDonationClick(ListItem<?> item){
|
||||||
|
UiUtils.launchWebBrowser(getActivity(), "https://sponsor.staging.joinmastodon.org/donate/manage");
|
||||||
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onSelfUpdateStateChanged(SelfUpdateStateChangedEvent ev){
|
public void onSelfUpdateStateChanged(SelfUpdateStateChangedEvent ev){
|
||||||
updateUpdateBanner();
|
updateUpdateBanner();
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="960"
|
||||||
|
android:viewportHeight="960">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M482,640L622,500Q639,483 644,458.5Q649,434 639,411Q629,388 609,374Q589,360 564,360Q539,360 519,375.5Q499,391 482,408Q464,391 444.5,375.5Q425,360 400,360Q375,360 354.5,373.5Q334,387 324,410Q314,433 319.5,457.5Q325,482 342,500L482,640ZM370,880L354,752Q341,747 329.5,740Q318,733 307,725L188,775L78,585L181,507Q180,500 180,493.5Q180,487 180,480Q180,473 180,466.5Q180,460 181,453L78,375L188,185L307,235Q318,227 330,220Q342,213 354,208L370,80L590,80L606,208Q619,213 630.5,220Q642,227 653,235L772,185L882,375L779,453Q780,460 780,466.5Q780,473 780,480Q780,487 780,493.5Q780,500 778,507L881,585L771,775L653,725Q642,733 630,740Q618,747 606,752L590,880L370,880ZM440,800L519,800L533,694Q564,686 590.5,670.5Q617,655 639,633L738,674L777,606L691,541Q696,527 698,511.5Q700,496 700,480Q700,464 698,448.5Q696,433 691,419L777,354L738,286L639,328Q617,305 590.5,289.5Q564,274 533,266L520,160L441,160L427,266Q396,274 369.5,289.5Q343,305 321,327L222,286L183,354L269,418Q264,433 262,448Q260,463 260,480Q260,496 262,511Q264,526 269,541L183,606L222,674L321,632Q343,655 369.5,670.5Q396,686 427,694L440,800ZM480,480L480,480Q480,480 480,480Q480,480 480,480L480,480L480,480L480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480L480,480L480,480L480,480Q480,480 480,480Q480,480 480,480L480,480L480,480L480,480Q480,480 480,480Q480,480 480,480L480,480L480,480L480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480L480,480L480,480L480,480Q480,480 480,480Q480,480 480,480L480,480L480,480Z"/>
|
||||||
|
</vector>
|
|
@ -0,0 +1,9 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="960"
|
||||||
|
android:viewportHeight="960">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M640,520L474,358Q443,328 421.5,291.5Q400,255 400,212Q400,157 438.5,118.5Q477,80 532,80Q564,80 592,93.5Q620,107 640,130Q660,107 688,93.5Q716,80 748,80Q803,80 841.5,118.5Q880,157 880,212Q880,255 859,291.5Q838,328 807,358L640,520ZM640,408L749,301Q768,282 784,260.5Q800,239 800,212Q800,190 785,175Q770,160 748,160Q734,160 721.5,165.5Q709,171 700,182L640,254L580,182Q571,171 558.5,165.5Q546,160 532,160Q510,160 495,175Q480,190 480,212Q480,239 496,260.5Q512,282 531,301L640,408ZM280,740L558,816L796,742Q791,733 781.5,726.5Q772,720 760,720L558,720Q531,720 515,718Q499,716 482,710L389,679L411,601L492,628Q509,633 532,636Q555,639 600,640L600,640Q600,640 600,640Q600,640 600,640Q600,629 593.5,619Q587,609 578,606L344,520Q344,520 344,520Q344,520 344,520L280,520L280,740ZM40,880L40,440L344,440Q351,440 358,441.5Q365,443 371,445L606,532Q639,544 659.5,574Q680,604 680,640L760,640Q810,640 845,673Q880,706 880,760L880,800L560,900L280,822L280,822L280,880L40,880ZM120,800L200,800L200,520L120,520L120,800ZM640,254L640,254Q640,254 640,254Q640,254 640,254Q640,254 640,254Q640,254 640,254Q640,254 640,254Q640,254 640,254L640,254L640,254Q640,254 640,254Q640,254 640,254Q640,254 640,254Q640,254 640,254Q640,254 640,254Q640,254 640,254L640,254Z"/>
|
||||||
|
</vector>
|
|
@ -775,4 +775,6 @@
|
||||||
<string name="donation_success_title">Thank you for your contribution!</string>
|
<string name="donation_success_title">Thank you for your contribution!</string>
|
||||||
<string name="donation_success_subtitle">You should receive an email confirming your donation soon.</string>
|
<string name="donation_success_subtitle">You should receive an email confirming your donation soon.</string>
|
||||||
<string name="donation_server_error">We are sorry, an error occurred and we have not been able to process your donation.\n\nPlease retry in a few minutes.</string>
|
<string name="donation_server_error">We are sorry, an error occurred and we have not been able to process your donation.\n\nPlease retry in a few minutes.</string>
|
||||||
|
<string name="settings_donate">Donate to Mastodon</string>
|
||||||
|
<string name="settings_manage_donations">Manage donations</string>
|
||||||
</resources>
|
</resources>
|
Loading…
Reference in New Issue