diff --git a/src/app/CitySelectorFragment.java b/src/app/CitySelectorFragment.java new file mode 100644 index 0000000..101d355 --- /dev/null +++ b/src/app/CitySelectorFragment.java @@ -0,0 +1,44 @@ +import android.app.AlertDialog; +import android.app.Fragment; +import android.view.View; +import android.widget.Toast; + +import java.util.ArrayList; +import java.util.List; + +public class CitySelectorFragment extends Fragment { + private List cities; + private List favoriteCities = new ArrayList<>(); + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_city_selector, container, false); + ListView cityListView = view.findViewById(R.id.city_list); + + // Пример списка городов + cities = Arrays.asList("Москва", "Санкт-Петербург", "Новосибирск", "Екатеринбург"); + + CityAdapter adapter = new CityAdapter(getContext(), cities); + cityListView.setAdapter(adapter); + + cityListView.setOnItemLongClickListener((parent, view1, position, id) -> { + String selectedCity = cities.get(position); + showDialog(selectedCity); + return true; + }); + + return view; + } + + private void showDialog(String city) { + new AlertDialog.Builder(getContext()) + .setTitle("Выбор города") + .setMessage("Добавить " + city + " в избранное?") + .setPositiveButton("В избранное", (dialog, which) -> { + favoriteCities.add(city); + Toast.makeText(getContext(), city + " добавлен в избранное", Toast.LENGTH_SHORT).show(); + }) + .setNegativeButton("Отмена", null) + .show(); + } +} diff --git a/src/app/build.gradle b/src/app/build.gradle index e3b27f0..15ace98 100644 --- a/src/app/build.gradle +++ b/src/app/build.gradle @@ -8,7 +8,7 @@ android { defaultConfig { applicationId "com.example.myapplication" - minSdk 31 + minSdk 30 targetSdk 34 versionCode 1 versionName "1.0" @@ -32,6 +32,9 @@ android { } dependencies { + + implementation libs.room.runtime + annotationProcessor libs.room.compiler implementation libs.appcompat implementation libs.material implementation libs.activity diff --git a/src/app/src/main/AndroidManifest.xml b/src/app/src/main/AndroidManifest.xml index 4849da5..4876344 100644 --- a/src/app/src/main/AndroidManifest.xml +++ b/src/app/src/main/AndroidManifest.xml @@ -18,16 +18,16 @@ android:exported="true" android:label="@string/title_activity_main2" android:theme="@style/Theme.MyApplication.NoActionBar"> + + - - \ No newline at end of file diff --git a/src/app/src/main/java/com/example/myapplication/AppDatabase.java b/src/app/src/main/java/com/example/myapplication/AppDatabase.java new file mode 100644 index 0000000..b7f7a10 --- /dev/null +++ b/src/app/src/main/java/com/example/myapplication/AppDatabase.java @@ -0,0 +1,37 @@ +package com.example.myapplication; + +import android.content.Context; + +import androidx.room.Database; +import androidx.room.Room; +import androidx.room.RoomDatabase; + +import com.example.myapplication.DAO.CityDao; +import com.example.myapplication.DAO.FavoriteCityDao; +import com.example.myapplication.DAO.UserDao; +import com.example.myapplication.DTO.City; +import com.example.myapplication.DTO.FavoriteCity; +import com.example.myapplication.DTO.User; + +@Database(entities = {User.class, City.class, FavoriteCity.class}, version = 1, exportSchema = false) +public abstract class AppDatabase extends RoomDatabase { + public abstract UserDao userDao(); + public abstract CityDao cityDao(); + public abstract FavoriteCityDao favoriteCityDao(); + +// public abstract WeatherDao weatherDao(); + private static volatile AppDatabase INSTANCE; + + public static AppDatabase getDatabase(final Context context) { + if (INSTANCE == null) { + synchronized (AppDatabase.class) { + if (INSTANCE == null) { + INSTANCE = Room.databaseBuilder(context.getApplicationContext(), + AppDatabase.class, "app_database") + .build(); + } + } + } + return INSTANCE; + } +} \ No newline at end of file diff --git a/src/app/src/main/java/com/example/myapplication/CustomAdapter.java b/src/app/src/main/java/com/example/myapplication/CustomAdapter.java index bdfec94..623e0a1 100644 --- a/src/app/src/main/java/com/example/myapplication/CustomAdapter.java +++ b/src/app/src/main/java/com/example/myapplication/CustomAdapter.java @@ -8,13 +8,14 @@ import android.widget.TextView; import androidx.recyclerview.widget.RecyclerView; -import java.util.ArrayList; +import com.example.myapplication.DTO.City; +import com.example.myapplication.DTO.WeatherData; + import java.util.List; public class CustomAdapter extends RecyclerView.Adapter { - private List localDataSet; - + private List localDataSet; public static class ViewHolder extends RecyclerView.ViewHolder { private final TextView textView; @@ -32,7 +33,7 @@ public class CustomAdapter extends RecyclerView.Adapter dataSet) { + public CustomAdapter(List dataSet) { localDataSet = dataSet; } @@ -52,7 +53,7 @@ public class CustomAdapter extends RecyclerView.Adapter getAllCity(); + + @Query("SELECT * FROM city_table WHERE id = :cityId") + City getCityById(int cityId); + + @Query("SELECT COUNT(*) FROM city_table") + int countCity(); + + @Query("SELECT * FROM city_table WHERE CityName = :city") + City getCityByName(String city); +} diff --git a/src/app/src/main/java/com/example/myapplication/DAO/FavoriteCityDao.java b/src/app/src/main/java/com/example/myapplication/DAO/FavoriteCityDao.java new file mode 100644 index 0000000..ff23e81 --- /dev/null +++ b/src/app/src/main/java/com/example/myapplication/DAO/FavoriteCityDao.java @@ -0,0 +1,27 @@ +package com.example.myapplication.DAO; + +import androidx.room.Dao; +import androidx.room.Insert; +import androidx.room.Query; + +import com.example.myapplication.DTO.FavoriteCity; + +import java.util.List; + +@Dao +public interface FavoriteCityDao { + @Insert + void insert(FavoriteCity favoriteCity); + + @Insert + void insertAll(FavoriteCity... favoriteCities); + + @Query("SELECT * FROM favorite_cities_table") + List getAllFavoriteCity(); + + @Query("SELECT * FROM favorite_cities_table WHERE owner_id = :ownerId") + List getFavoriteCityByOwnerId(long ownerId); + + @Query("SELECT * FROM favorite_cities_table WHERE owner_id = :userId AND city_id = :cityId") + int isFavorite(long userId, long cityId); +} diff --git a/src/app/src/main/java/com/example/myapplication/DAO/UserDao.java b/src/app/src/main/java/com/example/myapplication/DAO/UserDao.java new file mode 100644 index 0000000..575e6d0 --- /dev/null +++ b/src/app/src/main/java/com/example/myapplication/DAO/UserDao.java @@ -0,0 +1,27 @@ +package com.example.myapplication.DAO; + +import androidx.room.Dao; +import androidx.room.Insert; +import androidx.room.Query; + +import com.example.myapplication.DTO.User; + +import java.util.List; + +@Dao +public interface UserDao { + @Insert + void insert(User user); + + @Insert + void insertAll(User... users); + + @Query("SELECT * FROM user_table") + List getAllUsers(); + + @Query("SELECT password FROM user_table WHERE LOWER(name) = LOWER(:name)") + String getPasswordByName(String name); + + @Query("SELECT * FROM user_table WHERE LOWER(name) = LOWER(:username)") + User getUserByName(String username); +} \ No newline at end of file diff --git a/src/app/src/main/java/com/example/myapplication/DAO/WeatherDao.java b/src/app/src/main/java/com/example/myapplication/DAO/WeatherDao.java new file mode 100644 index 0000000..a1b77bb --- /dev/null +++ b/src/app/src/main/java/com/example/myapplication/DAO/WeatherDao.java @@ -0,0 +1,7 @@ +package com.example.myapplication.DAO; + +import androidx.room.Dao; + +@Dao +public class WeatherDao { +} diff --git a/src/app/src/main/java/com/example/myapplication/DTO/City.java b/src/app/src/main/java/com/example/myapplication/DTO/City.java new file mode 100644 index 0000000..f1d4418 --- /dev/null +++ b/src/app/src/main/java/com/example/myapplication/DTO/City.java @@ -0,0 +1,25 @@ +package com.example.myapplication.DTO; + +@androidx.room.Entity(tableName = "city_table") +public class City { + @androidx.room.PrimaryKey(autoGenerate = true) + private long id; + + public String CityName; + + public City(String CityName) { + this.CityName = CityName; + } + + public long getId() { + return id; + } + + public String getName() { + return CityName; + } + + public void setId(long id) { + this.id = id; + } +} diff --git a/src/app/src/main/java/com/example/myapplication/DTO/FavoriteCity.java b/src/app/src/main/java/com/example/myapplication/DTO/FavoriteCity.java new file mode 100644 index 0000000..718549d --- /dev/null +++ b/src/app/src/main/java/com/example/myapplication/DTO/FavoriteCity.java @@ -0,0 +1,60 @@ +package com.example.myapplication.DTO; + +import androidx.room.Entity; +import androidx.room.ForeignKey; +import androidx.room.Index; + +@Entity(tableName = "favorite_cities_table", + foreignKeys = { + @ForeignKey(entity = User.class, + parentColumns = "id", + childColumns = "owner_id", + onDelete = ForeignKey.CASCADE), + @ForeignKey(entity = City.class, + parentColumns = "id", + childColumns = "city_id", + onDelete = ForeignKey.CASCADE) + }, + indices = { + @Index(value = "owner_id"), + @Index(value = "city_id") + } +) +public class FavoriteCity { + @androidx.room.PrimaryKey(autoGenerate = true) + private long id; + + @androidx.room.ColumnInfo(name = "owner_id") + private long ownerId; + @androidx.room.ColumnInfo(name = "city_id") + private long cityId; + + public FavoriteCity(long ownerId, long cityId) { + this.ownerId = ownerId; + this.cityId = cityId; + } + + public long getId() { + return id; + } + + public long getOwnerId() { + return ownerId; + } + + public long getCityId() { + return cityId; + } + + public void setId(long id) { + this.id = id; + } + + public void setOwnerId(long ownerId) { + this.ownerId = ownerId; + } + + public void setCityId(long cityId) { + this.cityId = cityId; + } +} \ No newline at end of file diff --git a/src/app/src/main/java/com/example/myapplication/DTO/User.java b/src/app/src/main/java/com/example/myapplication/DTO/User.java new file mode 100644 index 0000000..69c4477 --- /dev/null +++ b/src/app/src/main/java/com/example/myapplication/DTO/User.java @@ -0,0 +1,33 @@ +package com.example.myapplication.DTO; + +import androidx.room.Entity; +import androidx.room.PrimaryKey; + +@Entity(tableName = "user_table") +public class User { + @PrimaryKey(autoGenerate = true) + private long id; + public String name; + public String password; + + public User(String name, String password) { + this.name = name; + this.password = password; + } + + public long getId() { + return id; + } + + public String getPassword() { + return password; + } + + public String getName() { + return name; + } + + public void setId(long id) { + this.id = id; + } +} diff --git a/src/app/src/main/java/com/example/myapplication/WeatherData.java b/src/app/src/main/java/com/example/myapplication/DTO/WeatherData.java similarity index 72% rename from src/app/src/main/java/com/example/myapplication/WeatherData.java rename to src/app/src/main/java/com/example/myapplication/DTO/WeatherData.java index e6415f4..8d895ce 100644 --- a/src/app/src/main/java/com/example/myapplication/WeatherData.java +++ b/src/app/src/main/java/com/example/myapplication/DTO/WeatherData.java @@ -1,6 +1,13 @@ -package com.example.myapplication; +package com.example.myapplication.DTO; +import androidx.room.Entity; +import androidx.room.PrimaryKey; + +@Entity(tableName = "weather_table") public class WeatherData { + @PrimaryKey(autoGenerate = true) + private long id; + public String City; public String Temperature; public String WeatherCondition; diff --git a/src/app/src/main/java/com/example/myapplication/DatabaseInitializer.java b/src/app/src/main/java/com/example/myapplication/DatabaseInitializer.java new file mode 100644 index 0000000..b65122e --- /dev/null +++ b/src/app/src/main/java/com/example/myapplication/DatabaseInitializer.java @@ -0,0 +1,44 @@ +package com.example.myapplication; + +import com.example.myapplication.DAO.CityDao; +import com.example.myapplication.DAO.FavoriteCityDao; +import com.example.myapplication.DAO.UserDao; +import com.example.myapplication.DTO.User; + +public class DatabaseInitializer { + public static void populateDatabase(final AppDatabase db) { + new Thread(() -> { + UserDao userDao = db.userDao(); + CityDao cityDao = db.cityDao(); + FavoriteCityDao favoriteCityDao = db.favoriteCityDao(); + // Создание начальных данных + User user1 = new User("Alice", "kek123"); + User user2 = new User("Bob", "kek123"); + User user3 = new User("Charlie", "kek123"); + User user4 = new User("David", "kek123"); + User user5 = new User("Eve", "kek123"); + userDao.insertAll(user1, user2, user3, user4, user5); + + // Создание городов +// City city1 = new City("Moscow"); +// City city2 = new City("Saint Petersburg"); +// City city3 = new City("Novosibirsk"); +// City city4 = new City("Yekaterinburg"); +// City city5 = new City("Kazan"); +// City city6 = new City("Chelyabinsk"); +// City city7 = new City("Omsk"); +// cityDao.insertAll(city1, city2, city3, city4, city5, city6, city7); + + // Создание связей между пользователями и городами +// FavoriteCity favoriteCity1 = new FavoriteCity(1, 1); +// FavoriteCity favoriteCity2 = new FavoriteCity(1, 2); +// FavoriteCity favoriteCity3 = new FavoriteCity(1, 3); +// FavoriteCity favoriteCity4 = new FavoriteCity(2, 4); +// FavoriteCity favoriteCity5 = new FavoriteCity(2, 5); +// FavoriteCity favoriteCity6 = new FavoriteCity(3, 6); +// FavoriteCity favoriteCity7 = new FavoriteCity(3, 7); +// favoriteCityDao.insertAll(favoriteCity1, favoriteCity2, favoriteCity3, favoriteCity4, favoriteCity5, favoriteCity6, favoriteCity7); + + }).start(); + } +} \ No newline at end of file diff --git a/src/app/src/main/java/com/example/myapplication/MainActivity.java b/src/app/src/main/java/com/example/myapplication/MainActivity.java index f3a8d19..dd0dee5 100644 --- a/src/app/src/main/java/com/example/myapplication/MainActivity.java +++ b/src/app/src/main/java/com/example/myapplication/MainActivity.java @@ -1,10 +1,12 @@ package com.example.myapplication; import android.content.Intent; +import android.content.SharedPreferences; import android.graphics.Color; import android.graphics.ColorMatrix; import android.graphics.ColorMatrixColorFilter; import android.os.Bundle; +import android.util.Log; import android.view.View; import android.widget.ImageView; @@ -13,12 +15,24 @@ import androidx.appcompat.app.AppCompatActivity; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; + import android.widget.EditText; +import com.example.myapplication.DAO.CityDao; +import com.example.myapplication.DAO.FavoriteCityDao; +import com.example.myapplication.DAO.UserDao; +import com.example.myapplication.DTO.City; +import com.example.myapplication.DTO.User; + +import java.util.List; +import java.util.concurrent.Executors; + public class MainActivity extends AppCompatActivity { EditText emailEditText; EditText passwordEditText; + private UserDao userDao; + AppDatabase db; @Override protected void onCreate(Bundle savedInstanceState) { @@ -34,23 +48,102 @@ public class MainActivity extends AppCompatActivity { emailEditText = findViewById(R.id.editTextTextEmailAddress); passwordEditText = findViewById(R.id.editTextTextPassword); + db = AppDatabase.getDatabase(this); + userDao = db.userDao(); + ImageView imageView = findViewById(R.id.imageView); ColorMatrix matrix = new ColorMatrix(); matrix.setSaturation(0); // Set saturation to 0 to make the image monochrome ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix); imageView.setColorFilter(filter); + + // Проверка первого запуска + SharedPreferences sharedPreferences = getSharedPreferences("app_prefs", MODE_PRIVATE); + boolean isFirstRun = sharedPreferences.getBoolean("isFirstRun", true); + + if (isFirstRun) { + // Заполнение базы данных начальными данными + DatabaseInitializer.populateDatabase(db); + + // Установка флага, что приложение уже запускалось + SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.putBoolean("isFirstRun", false); + editor.apply(); + } + // Тестовая фигня что бы показать + Executors.newSingleThreadExecutor().execute(() -> { + try { + FavoriteCityDao favoriteCityDao = db.favoriteCityDao(); + CityDao cityDao = db.cityDao(); + + Log.d("MainActivity", "-------------------------------\nAll users:"); + // Получение всех пользователей + List users = userDao.getAllUsers(); + for (User user : users) { + Log.d("User", user.getName()); + } + + if (cityDao.countCity() > 0) { + Log.d("MainActivity", "-------------------------------\nAll city:"); + // Получение всех городов + List cities = cityDao.getAllCity(); + for (City city : cities) { + Log.d("City", city.getName()); + } + } +// +// Log.d("MainActivity", "-------------------------------\nAll fav:"); +// // Получение всех связей +// List favoriteCities = favoriteCityDao.getAllFavoriteCity(); +// for (FavoriteCity favoriteCity : favoriteCities) { +// Log.d("FavoriteCity", "User: " + favoriteCity.getOwnerId() + ", City: " + favoriteCity.getCityId()); +// } + } catch (Exception e) { + Log.e("MainActivity", "Error: " + e.getMessage()); + } + }); } public void goToAnotherActivity(View view) { - String[] logins = getResources().getStringArray(R.array.passwords_array); - for (String login : logins) { - String[] parts = login.split("\\|"); - if (parts[0].equals(emailEditText.getText().toString()) && parts[1].equals(passwordEditText.getText().toString())) { - startActivity(new Intent(this, MainActivity2.class)); - } else { - emailEditText.setTextColor(Color.RED); - passwordEditText.setTextColor(Color.RED); + view.setEnabled(false); + + String enteredLogin = emailEditText.getText().toString(); + String enteredPassword = passwordEditText.getText().toString(); + + Executors.newSingleThreadExecutor().execute(() -> { + try { + String password = userDao.getPasswordByName(enteredLogin); + runOnUiThread(() -> { + if (enteredPassword.equals(password)) { + Intent intent = new Intent(MainActivity.this, MainActivity2.class); + intent.putExtra("userName", enteredLogin); + startActivity(intent); + } else { + emailEditText.setTextColor(Color.RED); + passwordEditText.setTextColor(Color.RED); + } + }); + } catch (Exception e) { + Log.e("MainActivity", "Error: " + e.getMessage()); + runOnUiThread(() -> { + emailEditText.setTextColor(Color.RED); + passwordEditText.setTextColor(Color.RED); + }); } - } + }); + + view.setEnabled(true); + +// String[] logins = getResources().getStringArray(R.array.passwords_array); +// +// for (String login : logins) { +// String[] parts = login.split("\\|"); +// if (parts[0].equals(emailEditText.getText().toString()) && parts[1].equals(passwordEditText.getText().toString())) { +// startActivity(new Intent(this, MainActivity2.class)); +// } else { +// emailEditText.setTextColor(Color.RED); +// passwordEditText.setTextColor(Color.RED); +// } +// } } } \ No newline at end of file diff --git a/src/app/src/main/java/com/example/myapplication/MainActivity2.java b/src/app/src/main/java/com/example/myapplication/MainActivity2.java index 1ac9b15..c98c698 100644 --- a/src/app/src/main/java/com/example/myapplication/MainActivity2.java +++ b/src/app/src/main/java/com/example/myapplication/MainActivity2.java @@ -1,10 +1,11 @@ package com.example.myapplication; +import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.Menu; -import com.example.myapplication.ui.home.HomeFragment; +import com.example.myapplication.DTO.WeatherData; import com.google.android.material.snackbar.Snackbar; import com.google.android.material.navigation.NavigationView; @@ -23,6 +24,12 @@ public class MainActivity2 extends AppCompatActivity { private ActivityMain2Binding binding; private WeatherData CurrentCity = new WeatherData("Город ещё не выбран","", "", "", ""); + private String userName = ""; + + public String getUserName() { + return userName; + } + public WeatherData getCurrentCity() { return CurrentCity; } @@ -34,6 +41,9 @@ public class MainActivity2 extends AppCompatActivity { binding = ActivityMain2Binding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); + Intent intent = getIntent(); + userName = intent.getStringExtra("userName"); + setSupportActionBar(binding.appBarMain.toolbar); binding.appBarMain.fab.setOnClickListener(new View.OnClickListener() { @Override diff --git a/src/app/src/main/java/com/example/myapplication/ui/gallery/GalleryFragment.java b/src/app/src/main/java/com/example/myapplication/ui/gallery/GalleryFragment.java index 4afcae1..a360ff6 100644 --- a/src/app/src/main/java/com/example/myapplication/ui/gallery/GalleryFragment.java +++ b/src/app/src/main/java/com/example/myapplication/ui/gallery/GalleryFragment.java @@ -12,7 +12,7 @@ import androidx.lifecycle.ViewModelProvider; import com.example.myapplication.MainActivity2; import com.example.myapplication.R; -import com.example.myapplication.WeatherData; +import com.example.myapplication.DTO.WeatherData; import com.example.myapplication.databinding.FragmentGalleryBinding; public class GalleryFragment extends Fragment { diff --git a/src/app/src/main/java/com/example/myapplication/ui/home/HomeFragment.java b/src/app/src/main/java/com/example/myapplication/ui/home/HomeFragment.java index ca6c6b1..6ef5f60 100644 --- a/src/app/src/main/java/com/example/myapplication/ui/home/HomeFragment.java +++ b/src/app/src/main/java/com/example/myapplication/ui/home/HomeFragment.java @@ -1,36 +1,37 @@ package com.example.myapplication.ui.home; +import android.app.AlertDialog; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; -import androidx.navigation.NavController; -import androidx.navigation.fragment.NavHostFragment; -import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; -import androidx.recyclerview.widget.SortedList; +import com.example.myapplication.AppDatabase; import com.example.myapplication.CustomAdapter; +import com.example.myapplication.DAO.CityDao; +import com.example.myapplication.DAO.FavoriteCityDao; +import com.example.myapplication.DAO.UserDao; +import com.example.myapplication.DTO.City; +import com.example.myapplication.DTO.FavoriteCity; +import com.example.myapplication.DTO.User; import com.example.myapplication.MainActivity2; import com.example.myapplication.R; import com.example.myapplication.RecyclerItemClickListener; -import com.example.myapplication.WeatherData; +import com.example.myapplication.DTO.WeatherData; import com.example.myapplication.databinding.FragmentHomeBinding; -import com.example.myapplication.ui.gallery.GalleryFragment; import com.google.gson.JsonArray; -import com.google.gson.JsonObject; -import java.io.Console; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; -import java.util.logging.Logger; +import java.util.concurrent.Executors; import retrofit2.Call; import retrofit2.Callback; @@ -44,6 +45,9 @@ public class HomeFragment extends Fragment { private FragmentHomeBinding binding; private WeatherService service; private ArrayList weatherDataList = new ArrayList<>(); + private List cityList = new ArrayList(); + + private RecyclerView recyclerView; public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @@ -53,16 +57,7 @@ public class HomeFragment extends Fragment { binding = FragmentHomeBinding.inflate(inflater, container, false); View root = binding.getRoot(); - Retrofit retrofit = new Retrofit.Builder() - .baseUrl("https://raw.githubusercontent.com/Lpirskaya/JsonLab/refs/heads/master/") - .addConverterFactory(GsonConverterFactory.create()) - .build(); - service = retrofit.create(WeatherService.class); - -// String[] city_list = getResources().getStringArray(R.array.city_list); -// Arrays.sort(city_list); - - RecyclerView recyclerView = root.findViewById(R.id.suslik); + recyclerView = root.findViewById(R.id.suslik); recyclerView.addOnItemTouchListener(new RecyclerItemClickListener(root.getContext(), recyclerView ,new RecyclerItemClickListener.OnItemClickListener() { @Override public void onItemClick(View view, int position) { Log.e("HomeFragment", "onClick: " + weatherDataList.get(position).City); @@ -73,16 +68,70 @@ public class HomeFragment extends Fragment { @Override public void onLongItemClick(View view, int position) { - + String selectedCity = weatherDataList.get(position).City; + showDialog(selectedCity); } })); recyclerView.setLayoutManager(new LinearLayoutManager(root.getContext())); - CustomAdapter adapter = new CustomAdapter(weatherDataList); + CustomAdapter adapter = new CustomAdapter(cityList); recyclerView.setAdapter(adapter); + Retrofit retrofit = new Retrofit.Builder() + .baseUrl("https://raw.githubusercontent.com/Lpirskaya/JsonLab/refs/heads/master/") + .addConverterFactory(GsonConverterFactory.create()) + .build(); + service = retrofit.create(WeatherService.class); + return root; } + private void showDialog(String city) { + new AlertDialog.Builder(getContext()) + .setTitle("Выбор города") + .setMessage("Добавить " + city + " в избранное?") + .setPositiveButton("В избранное", (dialog, which) -> { + if (getActivity() instanceof MainActivity2) { + String username = ((MainActivity2) getActivity()).getUserName(); + AppDatabase db = AppDatabase.getDatabase(getContext()); + + Executors.newSingleThreadExecutor().execute(() -> { + CityDao cityDao = db.cityDao(); + UserDao userDao = db.userDao(); + FavoriteCityDao favoriteCityDao = db.favoriteCityDao(); + City cityObj = cityDao.getCityByName(city); + User userObj = userDao.getUserByName(username); + + // check if city is already in favorites + if (userObj != null && cityObj != null) { + if (favoriteCityDao.isFavorite(userObj.getId(), cityObj.getId()) > 0) { + getActivity().runOnUiThread(() -> { + Toast.makeText(getContext(), city + " уже в избранном", Toast.LENGTH_SHORT).show(); + }); + return; + } + favoriteCityDao.insert(new FavoriteCity(userObj.getId(), cityObj.getId())); + getActivity().runOnUiThread(() -> { + Toast.makeText(getContext(), city + " добавлен в избранное", Toast.LENGTH_SHORT).show(); + }); + } else { + Log.e("HomeFragment", "User or city not found"); + } + + // Вывод всех связей + List favoriteCities = favoriteCityDao.getAllFavoriteCity(); + for (FavoriteCity favoriteCity : favoriteCities) { + Log.d("FavoriteCity", "User: " + favoriteCity.getOwnerId() + ", City: " + favoriteCity.getCityId()); + } + }); + + } else { + Log.e("HomeFragment", "Ошибка получения контекста"); + } + }) + .setNegativeButton("Отмена", null) + .show(); + } + public interface WeatherService { @GET("Weather2022.json") Call getWeather2022(); @@ -115,6 +164,7 @@ public class HomeFragment extends Fragment { )); weatherDataList.sort((o1, o2) -> o1.City.compareTo(o2.City)); + // JsonObject item = weatherData.get(i).getAsJsonObject(); // Log.i("HomeFragment", "City: " + item.get("City").getAsString()); // Log.i("HomeFragment", "Temperature: " + item.get("Temperature").getAsInt()); @@ -123,6 +173,21 @@ public class HomeFragment extends Fragment { // Log.i("HomeFragment", "Wind: " + item.get("Wind").getAsString()); // Log.i("HomeFragment", "-------------------"); } + + AppDatabase db = AppDatabase.getDatabase(getContext()); + CityDao cityDao = db.cityDao(); + Executors.newSingleThreadExecutor().execute(() -> { + if (cityDao.countCity() == 0) { + for (WeatherData wd : weatherDataList) { + Log.i("HomeFragment", "Inserting city: " + wd.City); + cityDao.insert(new City(wd.City)); + } + } + cityList = cityDao.getAllCity(); + getActivity().runOnUiThread(() -> { + recyclerView.setAdapter(new CustomAdapter(cityList)); + }); + }); } else Log.e("HomeFragment", "Request failed: " + response.message()); } diff --git a/src/app/src/main/res/layout/activity_main.xml b/src/app/src/main/res/layout/activity_main.xml index ecd77fa..77f59e7 100644 --- a/src/app/src/main/res/layout/activity_main.xml +++ b/src/app/src/main/res/layout/activity_main.xml @@ -34,8 +34,10 @@ android:layout_marginBottom="10sp" android:hint="@string/e_mail" android:inputType="textEmailAddress" + android:text="Alice" android:textAlignment="center" - tools:ignore="Autofill" /> + tools:ignore="Autofill" + tools:text="Alice" /> + tools:ignore="Autofill" + tools:text="kek123" /> diff --git a/src/gradle/libs.versions.toml b/src/gradle/libs.versions.toml index d647543..58b58ad 100644 --- a/src/gradle/libs.versions.toml +++ b/src/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -agp = "8.6.0" +agp = "8.7.2" junit = "4.13.2" junitVersion = "1.2.1" espressoCore = "3.6.1" @@ -12,6 +12,8 @@ lifecycleViewmodelKtx = "2.8.5" navigationFragment = "2.6.0" navigationUi = "2.6.0" retrofitVersion = "2.9.0" +roomRuntime = "2.6.1" +roomCompiler = "2.6.1" [libraries] converter-gson = { module = "com.squareup.retrofit2:converter-gson", version.ref = "retrofitVersion" } @@ -27,6 +29,8 @@ lifecycle-viewmodel-ktx = { group = "androidx.lifecycle", name = "lifecycle-view navigation-fragment = { group = "androidx.navigation", name = "navigation-fragment", version.ref = "navigationFragment" } navigation-ui = { group = "androidx.navigation", name = "navigation-ui", version.ref = "navigationUi" } retrofit2-retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofitVersion" } +room-compiler = { module = "androidx.room:room-compiler", version.ref = "roomCompiler" } +room-runtime = { module = "androidx.room:room-runtime", version.ref = "roomRuntime" } [plugins] android-application = { id = "com.android.application", version.ref = "agp" } diff --git a/src/gradle/wrapper/gradle-wrapper.properties b/src/gradle/wrapper/gradle-wrapper.properties index c9a231c..10235c1 100644 --- a/src/gradle/wrapper/gradle-wrapper.properties +++ b/src/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Fri Sep 20 13:46:49 MSK 2024 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists