diff --git a/app/src/main/java/com/example/updateapp/UpdateApplication.java b/app/src/main/java/com/example/updateapp/UpdateApplication.java index 71de640..4d22ba3 100644 --- a/app/src/main/java/com/example/updateapp/UpdateApplication.java +++ b/app/src/main/java/com/example/updateapp/UpdateApplication.java @@ -11,4 +11,14 @@ public class UpdateApplication extends Application { protected void attachBaseContext(Context base) { super.attachBaseContext(LocaleHelper.onAttach(base, "en")); } + + @Override + public void onCreate() { + super.onCreate(); + LocaleHelper.setLocale( + this, + LocaleHelper.getLanguage(this), + LocaleHelper.getCountry(this) + ); + } } \ No newline at end of file diff --git a/app/src/main/java/com/example/updateapp/adapters/LanguageAdapter.java b/app/src/main/java/com/example/updateapp/adapters/LanguageAdapter.java index f58709e..0d5a5fb 100644 --- a/app/src/main/java/com/example/updateapp/adapters/LanguageAdapter.java +++ b/app/src/main/java/com/example/updateapp/adapters/LanguageAdapter.java @@ -8,6 +8,7 @@ import android.widget.TextView; import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; import androidx.recyclerview.widget.RecyclerView; import com.example.updateapp.R; @@ -17,9 +18,9 @@ public class LanguageAdapter extends RecyclerView.Adapter { - private Context context; - private List languageList; - private OnLanguageSelectedListener listener; + private final Context context; + private final List languageList; + private final OnLanguageSelectedListener listener; public interface OnLanguageSelectedListener { void onLanguageSelected(LanguageModel language, int position); @@ -41,18 +42,21 @@ public LanguageViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int view @Override public void onBindViewHolder(@NonNull LanguageViewHolder holder, int position) { LanguageModel language = languageList.get(position); - holder.txtLanguageName.setText(language.getLanguageName()); - - if (language.isSelected()) { - holder.imgSelected.setVisibility(View.VISIBLE); - } else { - holder.imgSelected.setVisibility(View.GONE); - } + + boolean selected = language.isSelected(); + holder.itemView.setBackgroundResource( + selected ? R.drawable.bg_language_item_selected : R.drawable.bg_language_item + ); + holder.imgSelected.setVisibility(selected ? View.VISIBLE : View.INVISIBLE); + holder.txtLanguageName.setTextColor( + ContextCompat.getColor(context, selected ? R.color.themeColor : R.color.black) + ); + holder.itemView.setSelected(selected); holder.itemView.setOnClickListener(v -> { if (listener != null) { - listener.onLanguageSelected(language, position); + listener.onLanguageSelected(language, holder.getBindingAdapterPosition()); } }); } @@ -79,4 +83,4 @@ public LanguageViewHolder(@NonNull View itemView) { imgSelected = itemView.findViewById(R.id.img_selected); } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/example/updateapp/adapters/OnboardingAdapter.java b/app/src/main/java/com/example/updateapp/adapters/OnboardingAdapter.java index 065c59d..06bf04d 100644 --- a/app/src/main/java/com/example/updateapp/adapters/OnboardingAdapter.java +++ b/app/src/main/java/com/example/updateapp/adapters/OnboardingAdapter.java @@ -8,38 +8,36 @@ import android.widget.TextView; import androidx.annotation.NonNull; -import androidx.constraintlayout.widget.ConstraintLayout; import androidx.viewpager.widget.PagerAdapter; import com.example.updateapp.R; public class OnboardingAdapter extends PagerAdapter { - Context context; - LayoutInflater layoutInflater; + private final Context context; - public OnboardingAdapter(Context context) { - this.context = context; - } - - String titles[] = { - "Welcome to FinTrack", - "Track • Analyze • Improve", - "Build Better Money Habits" + private final int[] titles = { + R.string.onboarding_title_1, + R.string.onboarding_title_2, + R.string.onboarding_title_3 }; - String subtitles[] ={ - "Your all-in-one AI companion for smarter spending,\nbetter savings, and complete financial clarity." , - "Understand your expenses with clean visuals, smart insights, and real-time spending patterns\nthat keep you in control.", - "Set budgets, stay organized, and make confident \nfinancial decisions with powerful AI-Chatbot tools." + private final int[] subtitles = { + R.string.onboarding_subtitle_1, + R.string.onboarding_subtitle_2, + R.string.onboarding_subtitle_3 }; - int images[] = { + private final int[] images = { R.drawable.bg_1, R.drawable.bg_2, R.drawable.bg_3 }; + public OnboardingAdapter(Context context) { + this.context = context; + } + @Override public int getCount() { return titles.length; @@ -47,31 +45,28 @@ public int getCount() { @Override public boolean isViewFromObject(@NonNull View view, @NonNull Object object) { - return view == (ConstraintLayout) object; + return view == object; } @NonNull @Override public Object instantiateItem(@NonNull ViewGroup container, int position) { - layoutInflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE); - View v = layoutInflater.inflate(R.layout.slide, container, false); + View v = LayoutInflater.from(context).inflate(R.layout.slide, container, false); ImageView image = v.findViewById(R.id.slideImg); TextView title = v.findViewById(R.id.sliderTitle); TextView subtitle = v.findViewById(R.id.sliderSubTitle); image.setImageResource(images[position]); - title.setText(titles[position]); - subtitle.setText(subtitles[position]); + title.setText(context.getString(titles[position])); + subtitle.setText(context.getString(subtitles[position])); container.addView(v); - return v; - } @Override public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) { - container.removeView((ConstraintLayout) object); + container.removeView((View) object); } } diff --git a/app/src/main/java/com/example/updateapp/models/LanguageModel.java b/app/src/main/java/com/example/updateapp/models/LanguageModel.java index 9133124..56ac767 100644 --- a/app/src/main/java/com/example/updateapp/models/LanguageModel.java +++ b/app/src/main/java/com/example/updateapp/models/LanguageModel.java @@ -44,4 +44,4 @@ public boolean isSelected() { public void setSelected(boolean selected) { isSelected = selected; } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/example/updateapp/utils/LocaleHelper.java b/app/src/main/java/com/example/updateapp/utils/LocaleHelper.java index fab2da9..173a76b 100644 --- a/app/src/main/java/com/example/updateapp/utils/LocaleHelper.java +++ b/app/src/main/java/com/example/updateapp/utils/LocaleHelper.java @@ -5,99 +5,113 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.os.Build; +import android.os.LocaleList; + +import androidx.appcompat.app.AppCompatDelegate; +import androidx.core.os.LocaleListCompat; import java.util.Locale; -public class LocaleHelper { - private static final String SELECTED_LANGUAGE = "Locale.Helper.Selected.Language"; - private static final String SELECTED_COUNTRY = "Locale.Helper.Selected.Country"; +/** + * Single source of truth for the in-app language. + * English is stored and applied as {@code en} with no country, so Android falls + * back to {@code values/} instead of hunting for {@code values-en-rUS}. + */ +public final class LocaleHelper { + private static final String PREFS_NAME = "app_prefs"; + private static final String KEY_LANGUAGE = "Locale.Helper.Selected.Language"; + private static final String KEY_COUNTRY = "Locale.Helper.Selected.Country"; + public static final String DEFAULT_LANGUAGE = "en"; + + private LocaleHelper() {} public static Context onAttach(Context context) { - String lang = getPersistedData(context, "en"); - String country = getPersistedCountry(context, ""); - return setLocale(context, lang, country); + return onAttach(context, DEFAULT_LANGUAGE); } public static Context onAttach(Context context, String defaultLanguage) { - String lang = getPersistedData(context, defaultLanguage); - String country = getPersistedCountry(context, ""); - return setLocale(context, lang, country); + String lang = getLanguage(context, defaultLanguage); + String country = getCountry(context); + return updateResources(context, lang, country); } public static String getLanguage(Context context) { - return getPersistedData(context, "en"); + return getLanguage(context, DEFAULT_LANGUAGE); } - public static Context setLocale(Context context, String language, String country) { - persist(context, language, country); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - return updateResources(context, language, country); + public static String getLanguage(Context context, String defaultLanguage) { + SharedPreferences preferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE); + String lang = preferences.getString(KEY_LANGUAGE, defaultLanguage); + if (lang == null || lang.isEmpty()) { + return defaultLanguage; } - - return updateResourcesLegacy(context, language, country); + return lang; } - private static String getPersistedData(Context context, String defaultLanguage) { + public static String getCountry(Context context) { SharedPreferences preferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE); - return preferences.getString(SELECTED_LANGUAGE, defaultLanguage); + String country = preferences.getString(KEY_COUNTRY, ""); + return country == null ? "" : country; } - private static String getPersistedCountry(Context context, String defaultCountry) { - SharedPreferences preferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE); - return preferences.getString(SELECTED_COUNTRY, defaultCountry); + public static boolean isEnglish(String language) { + return language == null || language.isEmpty() || language.equalsIgnoreCase(DEFAULT_LANGUAGE); } - private static void persist(Context context, String language, String country) { - SharedPreferences preferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE); - SharedPreferences.Editor editor = preferences.edit(); - editor.putString(SELECTED_LANGUAGE, language); - editor.putString(SELECTED_COUNTRY, country); - editor.apply(); + public static Context setLocale(Context context, String language, String country) { + String lang = isEnglish(language) ? DEFAULT_LANGUAGE : language; + String region = isEnglish(lang) ? "" : (country == null ? "" : country); + persist(context, lang, region); + applyAppLocales(lang, region); + Context app = context.getApplicationContext(); + if (app != null && app != context) { + updateResources(app, lang, region); + } + return updateResources(context, lang, region); } - private static Context updateResources(Context context, String language, String country) { - Locale locale; + public static Locale toLocale(String language, String country) { + if (isEnglish(language)) { + return Locale.ENGLISH; + } if (country != null && !country.isEmpty()) { - locale = new Locale(language, country); - } else { - locale = new Locale(language); + return new Locale(language, country); } - Locale.setDefault(locale); + return new Locale(language); + } - Configuration configuration = context.getResources().getConfiguration(); - configuration.setLocale(locale); - configuration.setLayoutDirection(locale); + private static void persist(Context context, String language, String country) { + SharedPreferences.Editor editor = + context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE).edit(); + editor.putString(KEY_LANGUAGE, language); + editor.putString(KEY_COUNTRY, country == null ? "" : country); + editor.apply(); + } - return context.createConfigurationContext(configuration); + private static void applyAppLocales(String language, String country) { + String tag = isEnglish(language) + ? "en" + : (country != null && !country.isEmpty() ? language + "-" + country : language); + AppCompatDelegate.setApplicationLocales(LocaleListCompat.forLanguageTags(tag)); } - private static Context updateResourcesLegacy(Context context, String language, String country) { - Locale locale; - if (country != null && !country.isEmpty()) { - locale = new Locale(language, country); - } else { - locale = new Locale(language); - } + private static Context updateResources(Context context, String language, String country) { + Locale locale = toLocale(language, country); Locale.setDefault(locale); Resources resources = context.getResources(); - Configuration configuration = resources.getConfiguration(); - configuration.locale = locale; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { + Configuration configuration = new Configuration(resources.getConfiguration()); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + configuration.setLocale(locale); + configuration.setLocales(new LocaleList(locale)); configuration.setLayoutDirection(locale); + return context.createConfigurationContext(configuration); } + configuration.locale = locale; + configuration.setLayoutDirection(locale); resources.updateConfiguration(configuration, resources.getDisplayMetrics()); return context; } - - public static void clearLanguagePreference(Context context) { - SharedPreferences preferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE); - SharedPreferences.Editor editor = preferences.edit(); - editor.remove(SELECTED_LANGUAGE); - editor.remove(SELECTED_COUNTRY); - editor.apply(); - } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/example/updateapp/views/activites/LanguageActivity.java b/app/src/main/java/com/example/updateapp/views/activites/LanguageActivity.java index 67fe6a6..ac7a654 100644 --- a/app/src/main/java/com/example/updateapp/views/activites/LanguageActivity.java +++ b/app/src/main/java/com/example/updateapp/views/activites/LanguageActivity.java @@ -1,7 +1,9 @@ package com.example.updateapp.views.activites; +import android.content.Context; import android.content.Intent; import android.os.Bundle; +import android.view.View; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; @@ -14,6 +16,7 @@ import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import com.example.updateapp.Helpers.SaveState; import com.example.updateapp.MainActivity; import com.example.updateapp.R; import com.example.updateapp.adapters.LanguageAdapter; @@ -28,9 +31,17 @@ public class LanguageActivity extends AppCompatActivity implements LanguageAdapt private RecyclerView recyclerView; private LanguageAdapter languageAdapter; private List languageList; - private ImageView imgDone, imgBack; + private ImageView imgDone; + private ImageView imgBack; private TextView txtTitle; + private TextView txtSubtitle; private int selectedPosition = 0; + private boolean isFirstLaunch; + + @Override + protected void attachBaseContext(Context newBase) { + super.attachBaseContext(LocaleHelper.onAttach(newBase)); + } @Override protected void onCreate(Bundle savedInstanceState) { @@ -43,6 +54,8 @@ protected void onCreate(Bundle savedInstanceState) { return insets; }); + isFirstLaunch = getIntent().getBooleanExtra("isFirstLaunch", false); + initViews(); setupLanguageList(); setupRecyclerView(); @@ -50,23 +63,25 @@ protected void onCreate(Bundle savedInstanceState) { } private void initViews() { - recyclerView = findViewById(R.id.rev_langauge); + recyclerView = findViewById(R.id.rev_language); imgDone = findViewById(R.id.img_done); imgBack = findViewById(R.id.img_back); txtTitle = findViewById(R.id.txt_title); - - // Set title from string resource - txtTitle.setText(getString(R.string.language)); - - // Show back button - imgBack.setVisibility(android.view.View.VISIBLE); + txtSubtitle = findViewById(R.id.txt_subtitle); + + txtTitle.setText(getString(R.string.select_language)); + if (txtSubtitle != null) { + txtSubtitle.setText(getString(R.string.choose_language)); + } + + imgDone.setContentDescription(getString(R.string.done)); + imgBack.setContentDescription(getString(R.string.back)); + imgBack.setVisibility(isFirstLaunch ? View.GONE : View.VISIBLE); } private void setupLanguageList() { languageList = new ArrayList<>(); - - // Add all 10 supported languages - languageList.add(new LanguageModel(getString(R.string.lang_english), "en", "US")); + languageList.add(new LanguageModel(getString(R.string.lang_english), "en", "")); languageList.add(new LanguageModel(getString(R.string.lang_chinese), "zh", "CN")); languageList.add(new LanguageModel(getString(R.string.lang_hindi), "hi", "IN")); languageList.add(new LanguageModel(getString(R.string.lang_spanish), "es", "ES")); @@ -77,18 +92,16 @@ private void setupLanguageList() { languageList.add(new LanguageModel(getString(R.string.lang_russian), "ru", "RU")); languageList.add(new LanguageModel(getString(R.string.lang_urdu), "ur", "PK")); - // Set current language as selected String currentLanguage = LocaleHelper.getLanguage(this); + selectedPosition = 0; for (int i = 0; i < languageList.size(); i++) { - if (languageList.get(i).getLanguageCode().equals(currentLanguage)) { - languageList.get(i).setSelected(true); + boolean match = languageList.get(i).getLanguageCode().equalsIgnoreCase(currentLanguage); + languageList.get(i).setSelected(match); + if (match) { selectedPosition = i; - break; } } - - // If no match found, default to English (position 0) - if (selectedPosition == 0 && !currentLanguage.equals("en")) { + if (!languageList.get(selectedPosition).isSelected()) { languageList.get(0).setSelected(true); selectedPosition = 0; } @@ -98,12 +111,12 @@ private void setupRecyclerView() { languageAdapter = new LanguageAdapter(this, languageList, this); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setAdapter(languageAdapter); + recyclerView.setHasFixedSize(true); } private void setupClickListeners() { imgDone.setOnClickListener(v -> applyLanguageChange()); - - imgBack.setOnClickListener(v -> onBackPressed()); + imgBack.setOnClickListener(v -> getOnBackPressedDispatcher().onBackPressed()); } @Override @@ -113,33 +126,25 @@ public void onLanguageSelected(LanguageModel language, int position) { } private void applyLanguageChange() { - if (selectedPosition >= 0 && selectedPosition < languageList.size()) { - LanguageModel selectedLanguage = languageList.get(selectedPosition); - - // Apply the language change immediately - LocaleHelper.setLocale(this, selectedLanguage.getLanguageCode(), selectedLanguage.getCountryCode()); - - // Show success message - Toast.makeText(this, getString(R.string.language_changed), Toast.LENGTH_SHORT).show(); - - // Restart the main activity to apply changes completely - restartApp(); - } + LanguageModel selectedLanguage = languageList.get(selectedPosition); + LocaleHelper.setLocale( + this, + selectedLanguage.getLanguageCode(), + selectedLanguage.getCountryCode() + ); + + new SaveState(this, "LANGUAGE_SELECTED").setState(1); + Toast.makeText(this, getString(R.string.language_changed), Toast.LENGTH_SHORT).show(); + restartApp(); } private void restartApp() { - // Create intent to restart the main activity - Intent intent = new Intent(this, MainActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); + Intent intent = isFirstLaunch + ? new Intent(this, OnboardingActivity.class) + : new Intent(this, MainActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); startActivity(intent); finish(); - - // Apply transition animation overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out); } - - @Override - protected void attachBaseContext(android.content.Context newBase) { - super.attachBaseContext(LocaleHelper.onAttach(newBase)); - } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/example/updateapp/views/activites/LoginActivity.java b/app/src/main/java/com/example/updateapp/views/activites/LoginActivity.java index 8700ad9..e289845 100644 --- a/app/src/main/java/com/example/updateapp/views/activites/LoginActivity.java +++ b/app/src/main/java/com/example/updateapp/views/activites/LoginActivity.java @@ -222,7 +222,7 @@ public void onComplete(@NonNull Task task) { this, getString(R.string.google_signin_error, e.getStatusCode(), e.getMessage()), Toast.LENGTH_LONG - ).show(); + ) .show(); } } } diff --git a/app/src/main/java/com/example/updateapp/views/activites/OTPActivity.java b/app/src/main/java/com/example/updateapp/views/activites/OTPActivity.java index 918ed05..6d96226 100644 --- a/app/src/main/java/com/example/updateapp/views/activites/OTPActivity.java +++ b/app/src/main/java/com/example/updateapp/views/activites/OTPActivity.java @@ -224,7 +224,7 @@ private void saveUserToFirestoreAndContinue(String uid, String name, String emai }) .addOnFailureListener(e -> { if (dialog.isShowing()) dialog.dismiss(); - Toast.makeText(OTPActivity.this, "Failed to save user data: " + e.getMessage(), Toast.LENGTH_LONG).show(); + Toast.makeText(OTPActivity.this, getString(R.string.failed_save_user, e.getMessage()), Toast.LENGTH_LONG).show(); }); } diff --git a/app/src/main/java/com/example/updateapp/views/activites/SplashScreenActivity.java b/app/src/main/java/com/example/updateapp/views/activites/SplashScreenActivity.java index b2534dd..565a348 100644 --- a/app/src/main/java/com/example/updateapp/views/activites/SplashScreenActivity.java +++ b/app/src/main/java/com/example/updateapp/views/activites/SplashScreenActivity.java @@ -5,12 +5,9 @@ import android.os.Bundle; import android.view.WindowManager; -import androidx.activity.EdgeToEdge; import androidx.appcompat.app.AppCompatActivity; -import androidx.core.graphics.Insets; -import androidx.core.view.ViewCompat; -import androidx.core.view.WindowInsetsCompat; +import com.example.updateapp.Helpers.SaveState; import com.example.updateapp.R; import com.example.updateapp.utils.LocaleHelper; @@ -19,6 +16,11 @@ public class SplashScreenActivity extends AppCompatActivity { + @Override + protected void attachBaseContext(Context newBase) { + super.attachBaseContext(LocaleHelper.onAttach(newBase)); + } + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -28,25 +30,24 @@ protected void onCreate(Bundle savedInstanceState) { ); setContentView(R.layout.activity_splash_screen); + SaveState languageState = new SaveState(this, "LANGUAGE_SELECTED"); + boolean languageSelected = languageState.getState() == 1; new Timer().schedule(new TimerTask() { @Override public void run() { - runOnUiThread(new Runnable() { - @Override - public void run() { - Intent intent = new Intent(); - intent.setClass(SplashScreenActivity.this, OnboardingActivity.class); - startActivity(intent); - finish(); + runOnUiThread(() -> { + Intent intent; + if (!languageSelected) { + intent = new Intent(SplashScreenActivity.this, LanguageActivity.class); + intent.putExtra("isFirstLaunch", true); + } else { + intent = new Intent(SplashScreenActivity.this, OnboardingActivity.class); } + startActivity(intent); + finish(); }); } - },500); - } - - @Override - protected void attachBaseContext(Context newBase) { - super.attachBaseContext(LocaleHelper.onAttach(newBase)); + }, 500); } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/example/updateapp/views/fragments/ChatbotFragment.java b/app/src/main/java/com/example/updateapp/views/fragments/ChatbotFragment.java index 6ba8cb1..9218e8a 100644 --- a/app/src/main/java/com/example/updateapp/views/fragments/ChatbotFragment.java +++ b/app/src/main/java/com/example/updateapp/views/fragments/ChatbotFragment.java @@ -16,6 +16,7 @@ import android.widget.ImageView; import android.widget.Toast; +import com.example.updateapp.R; import com.example.updateapp.adapters.MessageAdapter; import com.example.updateapp.databinding.FragmentChatbotBinding; import com.example.updateapp.models.MessageModel; @@ -60,21 +61,21 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c binding.mic.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - Toast.makeText(getContext(), "coming soon", Toast.LENGTH_SHORT).show(); + Toast.makeText(getContext(), getString(R.string.coming_soon), Toast.LENGTH_SHORT).show(); } }); binding.btnHistory.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - Toast.makeText(getContext(), "coming soon", Toast.LENGTH_SHORT).show(); + Toast.makeText(getContext(), getString(R.string.coming_soon), Toast.LENGTH_SHORT).show(); } }); binding.file.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - Toast.makeText(getContext(), "coming soon", Toast.LENGTH_SHORT).show(); + Toast.makeText(getContext(), getString(R.string.coming_soon), Toast.LENGTH_SHORT).show(); } }); @@ -99,14 +100,14 @@ public void onResponse(String response) { public void onError(Throwable throwable) { if (getActivity() != null) { getActivity().runOnUiThread(() -> { - addToChat("Error: " + throwable.getMessage(), MessageModel.SENT_BY_BOT); + addToChat(getString(R.string.error_message, throwable.getMessage()), MessageModel.SENT_BY_BOT); }); } } }); } else { - Toast.makeText(getContext(), "write something", Toast.LENGTH_SHORT).show(); + Toast.makeText(getContext(), getString(R.string.write_something), Toast.LENGTH_SHORT).show(); } }); diff --git a/app/src/main/res/drawable/bg_language_item.xml b/app/src/main/res/drawable/bg_language_item.xml new file mode 100644 index 0000000..620a5e1 --- /dev/null +++ b/app/src/main/res/drawable/bg_language_item.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_language_item_selected.xml b/app/src/main/res/drawable/bg_language_item_selected.xml new file mode 100644 index 0000000..1aaea5b --- /dev/null +++ b/app/src/main/res/drawable/bg_language_item_selected.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/app/src/main/res/layout/activity_forget.xml b/app/src/main/res/layout/activity_forget.xml index 0a9947b..cb35f94 100644 --- a/app/src/main/res/layout/activity_forget.xml +++ b/app/src/main/res/layout/activity_forget.xml @@ -68,7 +68,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="8dp" - android:text="login" + android:text="@string/log_in" android:textColor="#FF5722" android:textStyle="bold" app:layout_constraintStart_toEndOf="@+id/textView6" diff --git a/app/src/main/res/layout/activity_language.xml b/app/src/main/res/layout/activity_language.xml index 7d11fac..ba62c06 100644 --- a/app/src/main/res/layout/activity_language.xml +++ b/app/src/main/res/layout/activity_language.xml @@ -1,172 +1,80 @@ - > - - - + android:layout_height="wrap_content" + android:background="@android:color/white" + android:gravity="center_vertical" + android:orientation="horizontal" + android:paddingStart="4dp" + android:paddingTop="8dp" + android:paddingEnd="12dp" + android:paddingBottom="8dp"> + android:padding="8dp" + android:src="@drawable/ic_back_arrow" + android:visibility="gone" /> - - - + android:layout_weight="1" + android:orientation="vertical" + android:paddingStart="8dp" + android:paddingEnd="8dp"> - + + + - - - - - + android:padding="4dp" + android:src="@drawable/ic_done_24" /> + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + android:layout_below="@id/rel_top" + android:clipToPadding="false" + android:paddingStart="12dp" + android:paddingTop="12dp" + android:paddingEnd="12dp" + android:paddingBottom="24dp" + tools:listitem="@layout/item_language" /> + diff --git a/app/src/main/res/layout/activity_new_update.xml b/app/src/main/res/layout/activity_new_update.xml index 42b6bd7..a652dfd 100644 --- a/app/src/main/res/layout/activity_new_update.xml +++ b/app/src/main/res/layout/activity_new_update.xml @@ -31,7 +31,7 @@ android:gravity="center_vertical" android:paddingTop="5dp" android:textStyle="bold" - android:text="Check what a new" + android:text="@string/check_new" android:textColor="@color/black" android:textSize="17sp"> @@ -93,7 +93,7 @@ android:layout_height="wrap_content" android:layout_centerInParent="true" android:gravity="center" - android:text="Advertisement Space" + android:text="@string/advertisement_space" android:textColor="@color/black" android:textSize="14sp" /> diff --git a/app/src/main/res/layout/activity_splash_screen.xml b/app/src/main/res/layout/activity_splash_screen.xml index a6f35b6..f9f90f6 100644 --- a/app/src/main/res/layout/activity_splash_screen.xml +++ b/app/src/main/res/layout/activity_splash_screen.xml @@ -88,7 +88,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="24dp" - android:text="AI-Powered Expense\nManager App" + android:text="@string/splash_title" android:textStyle="bold" android:textColor="@color/black" android:textSize="32dp" @@ -100,7 +100,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="2dp" - android:text="Track, manage, and analyze your finances\neffortlessly with AI-driven insights" + android:text="@string/splash_subtitle" android:textSize="16sp" app:layout_constraintStart_toStartOf="@+id/textView3" app:layout_constraintTop_toBottomOf="@+id/textView3" /> diff --git a/app/src/main/res/layout/fragment_chatbot.xml b/app/src/main/res/layout/fragment_chatbot.xml index 2d04a79..8cf8478 100644 --- a/app/src/main/res/layout/fragment_chatbot.xml +++ b/app/src/main/res/layout/fragment_chatbot.xml @@ -36,7 +36,7 @@ android:layout_marginEnd="100dp" android:layout_toStartOf="@+id/mic" android:layout_toEndOf="@+id/btnHistory" - android:text="Chatbot" + android:text="@string/chatbot" android:layout_centerVertical="true" android:singleLine="true" android:textSize="20sp" diff --git a/app/src/main/res/layout/item_language.xml b/app/src/main/res/layout/item_language.xml index e35f1a3..8a1aeb9 100644 --- a/app/src/main/res/layout/item_language.xml +++ b/app/src/main/res/layout/item_language.xml @@ -1,13 +1,15 @@ + android:paddingStart="16dp" + android:paddingTop="14dp" + android:paddingEnd="16dp" + android:paddingBottom="14dp"> + tools:text="@string/lang_english" /> - - - - \ No newline at end of file + android:tint="@color/themeColor" + android:visibility="invisible" /> + diff --git a/app/src/main/res/layout/item_message.xml b/app/src/main/res/layout/item_message.xml index 6855283..3a72eb7 100644 --- a/app/src/main/res/layout/item_message.xml +++ b/app/src/main/res/layout/item_message.xml @@ -29,7 +29,8 @@ android:layout_height="wrap_content" android:background="@drawable/send_message_back" android:padding="10dp" - android:text="How can I assist you today?" /> + android:text="" + tools:text="@string/chat_placeholder" /> + android:text="" + tools:text="@string/chat_placeholder" /> + android:title="@string/chatbot"/> + android:title="@string/profile"/> \ No newline at end of file diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index b77608a..e519f96 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -6,6 +6,7 @@ اللغة اختر اللغة + اختر اللغة التي تريد استخدامها English @@ -106,4 +107,17 @@ العودة إلى نسيت كلمة المرور يرجى التحقق من بريدك الإلكتروني - \ No newline at end of file + اكتب شيئاً + فشل حفظ المستخدم: %1$s + روبوت الدردشة + مساحة إعلانية + كيف يمكنني مساعدتك اليوم؟ + تطبيق إدارة المصروفات\nبالذكاء الاصطناعي + تتبع أموالك وأدرها وحلّلها\nبسهولة مع رؤى مدعومة بالذكاء الاصطناعي + مرحباً بك في FinTrack + تتبع • حلّل • حسّن + ابنِ عادات مالية أفضل + رفيقك الذكي لإنفاق أذكى،\nوتوفير أفضل، ووضوح مالي كامل. + افهم مصروفاتك عبر رسوم واضحة ورؤى ذكية وأنماط إنفاق فورية\nتبقيك مسيطراً. + حدد الميزانيات، وابقَ منظماً، واتخذ قرارات مالية\nواثقة باستخدام روبوت الدردشة الذكي. + diff --git a/app/src/main/res/values-bn/strings.xml b/app/src/main/res/values-bn/strings.xml index bd9a7c5..d75072e 100644 --- a/app/src/main/res/values-bn/strings.xml +++ b/app/src/main/res/values-bn/strings.xml @@ -6,6 +6,7 @@ ভাষা ভাষা নির্বাচন করুন + আপনি যে ভাষা ব্যবহার করতে চান তা বেছে নিন English @@ -106,4 +107,17 @@ ফিরে যান পাসওয়ার্ড ভুলে গেছেন অনুগ্রহ করে আপনার ইমেইল চেক করুন - \ No newline at end of file + কিছু লিখুন + ব্যবহারকারী সংরক্ষণ করতে ব্যর্থ: %1$s + চ্যাটবট + বিজ্ঞাপনের স্থান + আজ আমি আপনাকে কীভাবে সাহায্য করতে পারি? + AI-চালিত খরচ\nব্যবস্থাপক অ্যাপ + AI অন্তর্দৃষ্টি দিয়ে আপনার অর্থ সহজে\nট্র্যাক, পরিচালনা ও বিশ্লেষণ করুন + FinTrack-এ স্বাগতম + ট্র্যাক • বিশ্লেষণ • উন্নতি + ভালো অর্থ অভ্যাস গড়ুন + স্মার্ট খরচ, ভালো সঞ্চয় এবং পূর্ণ আর্থিক স্বচ্ছতার জন্য আপনার অল-ইন-ওয়ান AI সঙ্গী। + পরিষ্কার ভিজ্যুয়াল, স্মার্ট অন্তর্দৃষ্টি এবং রিয়েল-টাইম খরচের ধরন দিয়ে\nআপনার ব্যয় বুঝুন যা আপনাকে নিয়ন্ত্রণে রাখে। + বাজেট সেট করুন, সংগঠিত থাকুন, এবং শক্তিশালী AI-চ্যাটবট দিয়ে\nআত্মবিশ্বাসের সাথে আর্থিক সিদ্ধান্ত নিন। + diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index d402f79..0a1b00b 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -6,6 +6,7 @@ Idioma Seleccionar idioma + Elige el idioma que quieres usar English @@ -106,4 +107,17 @@ Volver a OLVIDÉ MI CONTRASEÑA Por Favor Revisa Tu Email - \ No newline at end of file + Escribe algo + No se pudo guardar el usuario: %1$s + Chatbot + Espacio publicitario + ¿Cómo puedo ayudarte hoy? + Gestor de gastos\ncon IA + Controla, gestiona y analiza tus finanzas\nsin esfuerzo con información impulsada por IA + Bienvenido a FinTrack + Registra • Analiza • Mejora + Mejores hábitos con el dinero + Tu compañero de IA para gastar mejor,\nahorrar más y tener claridad financiera. + Entiende tus gastos con visuales claros, ideas inteligentes y patrones en tiempo real\nque te mantienen al control. + Define presupuestos, organízate y toma decisiones financieras\ncon confianza usando el chatbot de IA. + diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 76ceeb4..a3a0dd7 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -6,6 +6,7 @@ Langue Sélectionner la langue + Choisissez la langue que vous souhaitez utiliser English @@ -106,4 +107,17 @@ Retour à MOT DE PASSE OUBLIÉ Veuillez Vérifier Votre Email - \ No newline at end of file + Écrivez quelque chose + Échec de l\'enregistrement de l\'utilisateur : %1$s + Chatbot + Espace publicitaire + Comment puis-je vous aider aujourd\'hui ? + Gestionnaire de dépenses\nalimenté par l\'IA + Suivez, gérez et analysez vos finances\nsans effort grâce à l\'IA + Bienvenue sur FinTrack + Suivre • Analyser • Améliorer + De meilleures habitudes d\'argent + Votre compagnon IA pour dépenser plus intelligemment,\nmieux épargner et y voir clair. + Comprenez vos dépenses avec des visuels clairs, des insights et des tendances en temps réel\npour rester maître de vos finances. + Fixez des budgets, restez organisé et prenez des décisions financières\nen toute confiance avec le chatbot IA. + diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index 780dcaf..36217e6 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -6,6 +6,7 @@ भाषा भाषा चुनें + वह भाषा चुनें जिसका आप उपयोग करना चाहते हैं English @@ -106,4 +107,17 @@ वापस जाएं पासवर्ड भूल गए कृपया अपना ईमेल जांचें - \ No newline at end of file + कुछ लिखें + उपयोगकर्ता सहेजने में विफल: %1$s + चैटबॉट + विज्ञापन स्थान + आज मैं आपकी कैसे मदद कर सकता हूँ? + AI-संचालित खर्च\nप्रबंधक ऐप + AI अंतर्दृष्टि के साथ अपने वित्त को\nआसानी से ट्रैक, प्रबंधित और विश्लेषित करें + FinTrack में आपका स्वागत है + ट्रैक • विश्लेषण • सुधार + बेहतर पैसे की आदतें बनाएं + समझदारी से खर्च, बेहतर बचत और पूरी वित्तीय स्पष्टता के लिए आपका ऑल-इन-वन AI साथी। + साफ विज़ुअल, स्मार्ट अंतर्दृष्टि और रियल-टाइम खर्च पैटर्न से अपने खर्च को समझें\nजो आपको नियंत्रण में रखते हैं। + बजट सेट करें, व्यवस्थित रहें, और शक्तिशाली AI-चैटबॉट टूल से\nआत्मविश्वास के साथ वित्तीय निर्णय लें। + diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index bc906cc..407e199 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -6,6 +6,7 @@ Idioma Selecionar idioma + Escolha o idioma que deseja usar English @@ -106,4 +107,17 @@ Voltar para ESQUECI A SENHA Por Favor Verifique Seu Email - \ No newline at end of file + Escreva algo + Falha ao salvar o usuário: %1$s + Chatbot + Espaço publicitário + Como posso ajudar hoje? + Gestor de despesas\ncom IA + Acompanhe, gerencie e analise suas finanças\nsem esforço com insights de IA + Bem-vindo ao FinTrack + Registrar • Analisar • Melhorar + Melhores hábitos com dinheiro + Seu companheiro de IA para gastar melhor,\npoupar mais e ter clareza financeira. + Entenda seus gastos com visuais claros, insights e padrões em tempo real\nque mantêm você no controle. + Defina orçamentos, organize-se e tome decisões financeiras\ncom confiança usando o chatbot de IA. + diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 61cd9fd..d596d67 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -6,6 +6,7 @@ Язык Выберите язык + Выберите язык, который хотите использовать English @@ -106,4 +107,17 @@ Вернуться к ЗАБЫЛИ ПАРОЛЬ Пожалуйста, Проверьте Ваш Email - \ No newline at end of file + Напишите что-нибудь + Не удалось сохранить пользователя: %1$s + Чат-бот + Рекламное место + Чем могу помочь сегодня? + Приложение для учёта\nрасходов с ИИ + Отслеживайте, управляйте и анализируйте финансы\nбез усилий с помощью ИИ + Добро пожаловать в FinTrack + Учёт • Анализ • Рост + Лучшие денежные привычки + Ваш ИИ-помощник для разумных трат,\nлучшей экономии и полной финансовой ясности. + Понимайте расходы с помощью наглядных графиков, умных подсказок и данных в реальном времени,\nчтобы всё держать под контролем. + Задавайте бюджеты, будьте организованны и принимайте уверенные финансовые решения\nс помощью ИИ-чата. + diff --git a/app/src/main/res/values-ur/strings.xml b/app/src/main/res/values-ur/strings.xml index 8417a1e..3ca6948 100644 --- a/app/src/main/res/values-ur/strings.xml +++ b/app/src/main/res/values-ur/strings.xml @@ -6,6 +6,7 @@ زبان زبان منتخب کریں + وہ زبان منتخب کریں جسے آپ استعمال کرنا چاہتے ہیں English @@ -106,4 +107,17 @@ واپس جائیں پاس ورڈ بھول گئے براہ کرم اپنا ای میل چیک کریں - \ No newline at end of file + کچھ لکھیں + صارف محفوظ کرنے میں ناکامی: %1$s + چیٹ بوٹ + اشتہاری جگہ + آج میں آپ کی کیسے مدد کر سکتا ہوں؟ + AI سے چلنے والا خرچ\nمینیجر ایپ + AI بصیرت کے ساتھ اپنے مالیات کو\nآسانی سے ٹریک، منظم اور تجزیہ کریں + FinTrack میں خوش آمدید + ٹریک • تجزیہ • بہتری + بہتر پیسے کی عادتیں بنائیں + ہوشیار خرچ، بہتر بچت اور مکمل مالی وضاحت کے لیے آپ کا آل ان ون AI ساتھی۔ + صاف بصری، اسمارٹ بصیرت اور حقیقی وقت کے خرچ کے انداز سے اپنے اخراجات سمجھیں\nجو آپ کو کنٹرول میں رکھتے ہیں۔ + بجٹ مقرر کریں، منظم رہیں، اور طاقتور AI-چیٹ بوٹ سے\nاعتماد کے ساتھ مالی فیصلے کریں۔ + diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index a9234f9..86bcd04 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -7,6 +7,7 @@ 语言 选择语言 + 选择您要使用的语言 English @@ -106,4 +107,17 @@ 验证码验证失败 验证码错误: %1$s 身份验证错误:登录后未找到用户 - \ No newline at end of file + 请输入内容 + 保存用户失败:%1$s + 聊天机器人 + 广告位 + 今天我能帮您什么? + AI 驱动的\n支出管理应用 + 借助 AI 洞察,轻松跟踪、管理和分析您的财务 + 欢迎使用 FinTrack + 记录 • 分析 • 改进 + 养成更好的理财习惯 + 您的一站式 AI 助手,帮您更聪明地消费、\n更好地储蓄,并看清财务全貌。 + 通过清晰图表、智能洞察和实时消费趋势\n了解支出,让一切尽在掌握。 + 设定预算、保持条理,并借助强大的 AI 聊天工具\n自信地做出财务决策。 + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 472e9d5..0940832 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -6,6 +6,7 @@ Language Select Language + Choose the language you want to use English @@ -105,4 +106,17 @@ Back to FORGET PASSWORD Please Check Your Email + Write something + Failed to save user: %1$s + Chatbot + Advertisement Space + How can I assist you today? + AI-Powered Expense\nManager App + Track, manage, and analyze your finances\neffortlessly with AI-driven insights + Welcome to FinTrack + Track • Analyze • Improve + Build Better Money Habits + Your all-in-one AI companion for smarter spending,\nbetter savings, and complete financial clarity. + Understand your expenses with clean visuals, smart insights, and real-time spending patterns\nthat keep you in control. + Set budgets, stay organized, and make confident \nfinancial decisions with powerful AI-Chatbot tools. \ No newline at end of file