diff --git a/app/src/main/java/com/example/citrusclient/views/OtherHomeFragment.java b/app/src/main/java/com/example/citrusclient/views/OtherHomeFragment.java new file mode 100644 index 0000000..4279181 --- /dev/null +++ b/app/src/main/java/com/example/citrusclient/views/OtherHomeFragment.java @@ -0,0 +1,514 @@ +package com.example.citrusclient.views; + +import android.app.Activity; +import android.content.Context; +import android.graphics.Color; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.lifecycle.Observer; +import androidx.lifecycle.ViewModelProvider; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.ImageButton; + +import com.example.citrusclient.Citrus; +import com.example.citrusclient.R; +import com.example.citrusclient.models.Book; +import com.example.citrusclient.models.Schedule; +import com.example.citrusclient.models.Todo; +import com.example.citrusclient.viewmodels.BooksViewModel; +import com.example.citrusclient.viewmodels.ScheduleViewModel; +import com.example.citrusclient.viewmodels.TodosViewModel; +import com.google.android.material.floatingactionbutton.FloatingActionButton; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; + +/** + * A simple {@link Fragment} subclass. + * Use the {@link OtherHomeFragment#newInstance} factory method to + * create an instance of this fragment. + */ +public class OtherHomeFragment extends Fragment { + + // TODO: Rename parameter arguments, choose names that match + // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER + private static final String ARG_PARAM1 = "param1"; + private static final String ARG_PARAM2 = "param2"; + + // TODO: Rename and change types of parameters + private String mParam1; + private String mParam2; + + public OtherHomeFragment() { + // Required empty public constructor + } + + /** + * Use this factory method to create a new instance of + * this fragment using the provided parameters. + * + * @param param1 Parameter 1. + * @param param2 Parameter 2. + * @return A new instance of fragment OtherHomeFragment. + */ + // TODO: Rename and change types and number of parameters + public static OtherHomeFragment newInstance(String param1, String param2) { + OtherHomeFragment fragment = new OtherHomeFragment(); + Bundle args = new Bundle(); + args.putString(ARG_PARAM1, param1); + args.putString(ARG_PARAM2, param2); + fragment.setArguments(args); + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if (getArguments() != null) { + mParam1 = getArguments().getString(ARG_PARAM1); + mParam2 = getArguments().getString(ARG_PARAM2); + } + + Citrus citrus = (Citrus)(getActivity().getApplication()); + year = citrus.getCurYear(); + month = citrus.getCurMonth(); + day = citrus.getCurDay(); + + todosViewModel = new ViewModelProvider(this).get(TodosViewModel.class); + scheduleViewModel = new ViewModelProvider(this).get(ScheduleViewModel.class); + booksViewModel = new ViewModelProvider(this).get(BooksViewModel.class); + + } + + @Override + public void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putInt("year", year); + outState.putInt("month", month); + outState.putInt("day", day); + } + + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + + return inflater.inflate(R.layout.fragment_home, container, false); + } + + private List todoList; + TodosViewModel todosViewModel; + private List scheduleList; + ScheduleViewModel scheduleViewModel; + + private HashMap integerBookHashMap; + BooksViewModel booksViewModel; + + LocalDate curDate; + + int year ; + int month; + int day; + + + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + Citrus citrus = (Citrus)(getActivity().getApplication()); + String token = citrus.getToken(); + String accountId = citrus.getCurLookingAccountId(); + System.out.println(token); + curDate = LocalDate.of(year, month, day); + + todoList = new ArrayList<>(); + scheduleList = new ArrayList<>(); + + Button curDateButton = view.findViewById(R.id.date_button); + curDateButton.setText(year + "年" + month + "月" + day + "日"); + + + RecyclerView todoRecyclerView = view.findViewById(R.id.my_todos_list); + todoRecyclerView.setHasFixedSize(true); + RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(view.getContext()); + todoRecyclerView.setLayoutManager(layoutManager); + MyOtherTodoshelfAdapter todoAdapter = new MyOtherTodoshelfAdapter(todoList, integerBookHashMap, todosViewModel, getActivity()); + todoRecyclerView.setAdapter(todoAdapter); + + RecyclerView scheduleRecyclerView = view.findViewById(R.id.my_schedule_list); + scheduleRecyclerView.setHasFixedSize(true); + RecyclerView.LayoutManager scheduleLayoutManager = new LinearLayoutManager(view.getContext()); + scheduleRecyclerView.setLayoutManager(scheduleLayoutManager); + MyOtherScheduleshelfAdapter scheduleAdapter = new MyOtherScheduleshelfAdapter(scheduleList, integerBookHashMap, curDate, getActivity()); + scheduleRecyclerView.setAdapter(scheduleAdapter); + + Button dateButton = view.findViewById(R.id.date_button); + dateButton.setOnClickListener(v -> { + ((MainActivity) getActivity()).showFragment(new OtherCalendarFragment()); + }); + + ImageButton prevBotton = view.findViewById(R.id.prev_day_botton); + prevBotton.setOnClickListener(v -> { + curDate = curDate.minusDays(1); + year = curDate.getYear(); + month = curDate.getMonthValue(); + day = curDate.getDayOfMonth(); + curDateButton.setText(year + "年" + month + "月" + day + "日"); + + scheduleAdapter.updateCurDate(curDate); + updateTodoSchedule(integerBookHashMap); + }); + + ImageButton nextBotton = view.findViewById(R.id.next_day_botton); + nextBotton.setOnClickListener(v -> { + curDate = curDate.plusDays(1); + year = curDate.getYear(); + month = curDate.getMonthValue(); + day = curDate.getDayOfMonth(); + curDateButton.setText(year + "年" + month + "月" + day + "日"); + + scheduleAdapter.updateCurDate(curDate); + updateTodoSchedule(integerBookHashMap); + + }); + + + booksViewModel.loadBooks(accountId, token); + scheduleViewModel.updateSchedulesByDay(accountId, year, month, day, token); + System.out.println(token); + + booksViewModel.getBookLiveData().observe(getViewLifecycleOwner(), new Observer>() { + @Override + public void onChanged(HashMap idBookHashMap) { + updateTodoSchedule(idBookHashMap); + } + }); + + todosViewModel.getTodosByDayLiveData().observe(getViewLifecycleOwner(), new Observer>() { + @Override + public void onChanged(HashMap idTodoHashMap) { + if(idTodoHashMap != null) { + for(Todo todo : idTodoHashMap.values()){ + if(!todo.containsTodo(todoList)){ + todoList.add(todo); + } + } + todoAdapter.setTodos(todoList, integerBookHashMap); + } else { + todoAdapter.setTodos(todoList, integerBookHashMap); + } + } + }); + + scheduleViewModel.getSchedulesByDay().observe(getViewLifecycleOwner(), new Observer>() { + @Override + public void onChanged(HashMap idScheduleHashMap) { + if(idScheduleHashMap != null) { + scheduleList = new ArrayList<>(idScheduleHashMap.values()); + scheduleAdapter.setSchedules(scheduleList, integerBookHashMap); + } else { + scheduleList = new ArrayList<>(); + scheduleAdapter.setSchedules(scheduleList, integerBookHashMap); + } + } + }); + + + } + + + private void updateTodoSchedule(HashMap idBookHashMap) { + Citrus citrus = (Citrus)(getActivity().getApplication()); + String token = citrus.getToken(); + String accountId = citrus.getCurLookingAccountId(); + int curBookId = citrus.getCurLookingBookId(); + + if (idBookHashMap != null) { + if(curBookId != -1) { + todoList = new ArrayList<>(); + integerBookHashMap = new HashMap<>(); + Book book = idBookHashMap.get(curBookId); + integerBookHashMap.put(curBookId, book); + todosViewModel.loadTodosByDay(accountId, curBookId, year, month, day, token); + } else { + todoList = new ArrayList<>(); + integerBookHashMap = new HashMap<>(idBookHashMap); + for (Book book : integerBookHashMap.values()) { + todosViewModel.loadTodosByDay(accountId, book.getBookId(), year, month, day, token); + } + } + } + scheduleViewModel.updateSchedulesByDay(accountId, year, month, day, token); + } + + + + @Override + public void onStop() { + super.onStop(); + booksViewModel.getBookLiveData().removeObservers(getViewLifecycleOwner()); + } + + +} + +class MyOtherTodoshelfAdapter extends RecyclerView.Adapter { + private List todoList; + private HashMap idBookHashMap; + private TodosViewModel todosViewModel; + private Context context; + + + MyOtherTodoshelfAdapter(List todos, HashMap idBookHashMap, TodosViewModel todosViewModel, Context context) { + this.todoList = todos; + this.todosViewModel = todosViewModel; + if (idBookHashMap != null) { + this.idBookHashMap = new HashMap<>(idBookHashMap); + } else { + this.idBookHashMap = new HashMap<>(); // 空のHashMapを作成 + } + this.context = context; + } + + public void setTodos(List todos ,HashMap idBookHashMap) { + todoList = todos; + if (idBookHashMap != null) { + this.idBookHashMap = new HashMap<>(idBookHashMap); + } else { + this.idBookHashMap = new HashMap<>(); // 空のHashMapを作成 + } + + sortTodosById(); + notifyDataSetChanged(); + } + + @NonNull + @Override + public MyTodoViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.a_todo, parent, false); + return new MyTodoViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull MyTodoViewHolder holder, int position) { + Activity activity = (Activity) context; + Citrus citrus = (Citrus)(activity.getApplication()); + String token = citrus.getToken(); + String accountId = citrus.getCurLookingAccountId(); + + Todo todoData = this.todoList.get(position); + holder.todoButton.setText(todoData.getTitle()); + holder.todoCheckBox.setChecked(todoData.getCheck()); + Book book = idBookHashMap.get(todoData.getBookId()); + if(book != null) { + int red = Integer.parseInt(book.getColor().substring(1, 3), 16); + int green = Integer.parseInt(book.getColor().substring(3, 5), 16); + int blue = Integer.parseInt(book.getColor().substring(5, 7), 16); + holder.todoButton.setBackgroundColor(Color.rgb(red, green, blue)); + holder.todoButton.setTextColor(Color.rgb(255 - red, 255 - green, 255 - blue)); + } + + holder.todoButton.setOnClickListener(v -> { + ((MainActivity) activity).showFragment(new CreateTodoFragment(todoData, book)); + }); + + holder.todoCheckBox.setOnCheckedChangeListener((buttonView, isChecked) -> { + // チェック状態が変更された時の処理を記述 + if (isChecked) { + // チェックされた時の処理 + todosViewModel.setCheck(accountId, book.getBookId(), todoData.getYear(), todoData.getMonth(), todoData.getDay(), todoData.getTodoId(), true, token); + } else { + // チェックが外された時の処理 + todosViewModel.setCheck(accountId, book.getBookId(), todoData.getYear(), todoData.getMonth(), todoData.getDay(), todoData.getTodoId(), false, token); + } + }); + + } + + @Override + public int getItemCount() { + return todoList.size(); + } + + private void sortTodosById() { + Collections.sort(todoList, new Comparator() { + @Override + public int compare(Todo todo1, Todo todo2) { + int bookComparison = Integer.compare(todo1.getBookId(), todo2.getBookId()); + if (bookComparison != 0) { + return bookComparison; // bookIdでの比較 + } + return Integer.compare(todo1.getTodoId(), todo2.getTodoId()); // 同じbookIdの場合、todoIdで比較 + } + }); + } + + + static class MyTodoViewHolder extends RecyclerView.ViewHolder { + Button todoButton; + CheckBox todoCheckBox; + public MyTodoViewHolder(@NonNull View itemView) { + super(itemView); + todoButton = itemView.findViewById(R.id.todo_button); + todoCheckBox = itemView.findViewById(R.id.todo_checkBox); + } + } +} + +class MyOtherScheduleshelfAdapter extends RecyclerView.Adapter { + + private List scheduleList; + private HashMap idBookHashMap; + private Context context; + private LocalDate curDate; + + MyOtherScheduleshelfAdapter(List schedules, HashMap idBookHashMap, LocalDate curDate, Context context) { + this.scheduleList = schedules; + if (idBookHashMap != null) { + this.idBookHashMap = new HashMap<>(idBookHashMap); + } else { + this.idBookHashMap = new HashMap<>(); // 空のHashMapを作成 + } + this.curDate = curDate; + this.context = context; + } + + public void setSchedules(List schedules, HashMap idBookHashMap) { + scheduleList = schedules; + if (idBookHashMap != null) { + this.idBookHashMap = new HashMap<>(idBookHashMap); + } else { + this.idBookHashMap = new HashMap<>(); // 空のHashMapを作成 + } + sortScheduleByTime(); + notifyDataSetChanged(); + } + + @NonNull + @Override + public MyScheduleViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.a_schedule, parent, false); + return new MyScheduleViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull MyScheduleViewHolder holder, int position) { + Activity activity = (Activity) context; + + int red = 169; + int green = 169; + int blue = 169; + Schedule scheduleData = this.scheduleList.get(position); + holder.scheduleButton.setText(scheduleData.getTitle()); + holder.scheduleButton.setText(scheduleData.getTitle() + "\n" + extractionTime(scheduleData.getStartTime(), curDate) + " ~ " + extractionTime(scheduleData.getEndTime(), curDate)); + Book book = idBookHashMap.get(scheduleData.getBookId()); + if(book != null) { + red = Integer.parseInt(book.getColor().substring(1, 3), 16); + green = Integer.parseInt(book.getColor().substring(3, 5), 16); + blue = Integer.parseInt(book.getColor().substring(5, 7), 16); + } + holder.scheduleButton.setBackgroundColor(Color.rgb(red, green, blue)); + holder.scheduleButton.setTextColor(Color.rgb(255 - red, 255 - green, 255 - blue)); + + holder.scheduleButton.setOnClickListener(v -> { + ((MainActivity) activity).showFragment(new CreateScheduleFragment(scheduleData, book)); + }); + } + + + + private void sortScheduleByTime() { + Collections.sort(scheduleList, new Comparator() { + @Override + public int compare(Schedule schedule1, Schedule schedule2) { + long start = convertTimeInteger(schedule1.getStartTime()); + long end = convertTimeInteger(schedule2.getStartTime()); + return Long.compare(start, end); + } + }); + notifyDataSetChanged(); // データ変更をアダプタに通知 + } + + private static long convertTimeInteger(String scheduleTime) { + try { + // フォーマッタを定義 + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm"); + + // StringをLocalDateTimeに変換 + LocalDateTime dateTime = LocalDateTime.parse(scheduleTime, formatter); + + // 年、月、日、時、分を抽出 + long year = dateTime.getYear(); + long month = dateTime.getMonthValue(); + long day = dateTime.getDayOfMonth(); + long hour = dateTime.getHour(); + long minute = dateTime.getMinute(); + + // 必要に応じて整数を組み合わせる(例: YYYYMMDDHHMM) + long result = year *100000000 +month * 1000000 + day * 10000 + hour * 100 + minute; + + return result; + } catch (DateTimeParseException e) { + e.printStackTrace(); + return -1; // エラーが発生した場合は-1を返す + } + } + + private static String extractionTime(String scheduleTime, LocalDate curDate) { + int year = curDate.getYear(); + int month = curDate.getMonthValue(); + int day = curDate.getDayOfMonth(); + long yearMonthDay = year * 10000 + month * 100 + day; + long scheduleYMD = convertTimeInteger(scheduleTime) / 10000; +// long scheduleYearMonth = extractUpperDigits(convertTimeInteger(scheduleTime), 8); + if(yearMonthDay > scheduleYMD) { + return "00:00"; + } else if(yearMonthDay < scheduleYMD) { + return "23:59"; + } else { + return scheduleTime.substring(scheduleTime.length() - 5); + } + } + +// public static long extractUpperDigits(long number, int digitCount) { +// // 10の累乗を計算 +// long divisor = (long) Math.pow(10, String.valueOf(number).length() - digitCount); +// return number / divisor; // 上位の桁を抽出 +// } + + // curDateを更新するメソッドを追加 + public void updateCurDate(LocalDate newCurDate) { + this.curDate = newCurDate; + notifyDataSetChanged(); // 必要に応じてアダプターをリフレッシュ + } + + @Override + public int getItemCount() { + return scheduleList.size(); + } + + static class MyScheduleViewHolder extends RecyclerView.ViewHolder { + Button scheduleButton; + public MyScheduleViewHolder(@NonNull View itemView) { + super(itemView); + scheduleButton = itemView.findViewById(R.id.schedule_button); + } + } +}