14
14
import android .os .Build ;
15
15
import android .os .Bundle ;
16
16
import android .os .Environment ;
17
+ import android .os .Handler ;
18
+ import android .os .Looper ;
17
19
import android .provider .CalendarContract ;
18
20
import android .provider .MediaStore ;
19
21
import android .provider .Settings ;
31
33
import androidx .core .app .ActivityCompat ;
32
34
import androidx .core .content .ContextCompat ;
33
35
import androidx .core .content .FileProvider ;
36
+ import androidx .recyclerview .widget .LinearLayoutManager ;
37
+ import androidx .recyclerview .widget .RecyclerView ;
34
38
35
39
import com .bumptech .glide .Glide ;
36
40
import com .bumptech .glide .request .target .CustomTarget ;
37
41
import com .bumptech .glide .request .transition .Transition ;
42
+ import com .fasterxml .jackson .databind .JsonNode ;
43
+ import com .fasterxml .jackson .databind .ObjectMapper ;
38
44
import com .luka .anidroid .R ;
45
+ import com .luka .anidroid .adapter .MusicVideoAdapter ;
39
46
import com .luka .anidroid .manager .FavoritesManager ;
40
47
import com .luka .anidroid .model .Anime ;
48
+ import com .luka .anidroid .model .MusicVideo ;
49
+
50
+ import org .json .JSONArray ;
51
+ import org .json .JSONException ;
41
52
42
53
import java .io .File ;
43
54
import java .io .FileNotFoundException ;
44
55
import java .io .FileOutputStream ;
45
56
import java .io .IOException ;
46
57
import java .io .OutputStream ;
58
+ import java .util .ArrayList ;
59
+ import java .util .List ;
60
+ import java .util .concurrent .ExecutorService ;
61
+ import java .util .concurrent .Executors ;
47
62
import java .util .concurrent .TimeUnit ;
48
63
64
+ import okhttp3 .OkHttpClient ;
65
+ import okhttp3 .Request ;
66
+ import okhttp3 .Response ;
67
+
49
68
public class AnimeDetailsActivity extends AppCompatActivity {
50
69
51
70
private FavoritesManager favoritesManager ;
52
71
private Anime anime ;
53
72
private Button favoriteButton ;
54
-
73
+ List <MusicVideo > musicVideos ;
74
+ OkHttpClient client = new OkHttpClient ();
75
+ ObjectMapper objectMapper = new ObjectMapper ();
76
+ MusicVideoAdapter musicVideoAdapter ;
55
77
private static final int WRITE_EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE = 1 ;
56
78
private static final int WRITE_CALENDAR_PERMISSION_REQUEST_CODE = 2 ;
57
79
@@ -155,6 +177,12 @@ public void onClick(View v) {
155
177
});
156
178
TextView episodesTextView = findViewById (R .id .anime_episodes );
157
179
favoriteButton = findViewById (R .id .btn_favorite );
180
+ TextView durationTextView = findViewById (R .id .anime_duration );
181
+ TextView popularityTextView = findViewById (R .id .anime_popularity );
182
+ TextView titleNativeTextView = findViewById (R .id .anime_title_native );
183
+ TextView seasonTextView = findViewById (R .id .anime_season );
184
+ TextView statusTextView = findViewById (R .id .anime_status );
185
+ TextView typeTextView = findViewById (R .id .anime_type );
158
186
159
187
if (anime .getImageUrl () != null && !anime .getImageUrl ().isEmpty ()) {
160
188
Glide .with (this )
@@ -168,10 +196,16 @@ public void onClick(View v) {
168
196
.into (imageView );
169
197
}
170
198
titleTextView .setText (anime .getTitle ());
171
- descriptionTextView .setText (anime .getDescription ());
172
- scoreTextView .setText (String .valueOf (anime .getAverageScore ()));
173
- broadcastDayTextView .setText (anime .getBroadcastDay ());
174
- episodesTextView .setText (String .valueOf (anime .getEpisodes ()));
199
+ descriptionTextView .setText ("Description: " + anime .getDescription ());
200
+ scoreTextView .setText ("Score: " + String .valueOf (anime .getAverageScore ()));
201
+ broadcastDayTextView .setText ("Broadcast day: " + anime .getBroadcastDay ());
202
+ episodesTextView .setText ("Number of episodes: " + String .valueOf (anime .getEpisodes ()));
203
+ durationTextView .setText ("Duration: " + anime .getDuration ());
204
+ popularityTextView .setText ("Popularity: " + String .valueOf (anime .getPopularity ()));
205
+ titleNativeTextView .setText ("Title (native): " + anime .getTitleNative ());
206
+ seasonTextView .setText ("Season: " + anime .getSeason ());
207
+ statusTextView .setText ("Status: " + anime .getStatus ());
208
+ typeTextView .setText ("Type: " + anime .getType ());
175
209
176
210
favoriteButton .setOnClickListener (v -> {
177
211
if (favoritesManager .isFavorite (anime )) {
@@ -185,6 +219,65 @@ public void onClick(View v) {
185
219
});
186
220
187
221
updateFavoriteButton ();
222
+
223
+ RecyclerView musicVideoRecyclerView = findViewById (R .id .music_video_recycler_view );
224
+ musicVideoRecyclerView .setLayoutManager (new LinearLayoutManager (this , LinearLayoutManager .HORIZONTAL , false ));
225
+ musicVideos = new ArrayList <>();
226
+ fetchMusicVideos (anime .getId ());
227
+ musicVideoAdapter = new MusicVideoAdapter (musicVideos , this );
228
+ musicVideoRecyclerView .setAdapter (musicVideoAdapter );
229
+ }
230
+
231
+ private void fetchMusicVideos (int id ) {
232
+ ExecutorService executor = Executors .newSingleThreadExecutor ();
233
+ Handler handler = new Handler (Looper .getMainLooper ());
234
+
235
+ executor .execute (() -> {
236
+ try {
237
+ Request request = new Request .Builder ()
238
+ .url ("https://api.jikan.moe/v4/anime/" + id + "/videos" )
239
+ .build ();
240
+
241
+ Response response = client .newCall (request ).execute ();
242
+ String responseBody = response .body ().string ();
243
+
244
+ // if the response is not successful, throw an exception
245
+ if (!response .isSuccessful ()) {
246
+ throw new IOException ("Unexpected code " + response );
247
+ }
248
+ Log .d ("HomeFragment" , "Response: " + responseBody );
249
+
250
+ JsonNode root = objectMapper .readTree (responseBody );
251
+ List <MusicVideo > newAnimeList = new ArrayList <>();
252
+
253
+ JsonNode data = root .get ("data" );
254
+ Log .d ("HomeFragment" , "Data: " + data .toString ());
255
+ Log .d ("HomeFragment" , "Music videos: " + data .get ("music_videos" ).toString ());
256
+ JsonNode musicVideosNode = data .get ("music_videos" );
257
+
258
+ for (JsonNode animeVideoNode : musicVideosNode ) {
259
+ MusicVideo animeMusicVideo = new MusicVideo ();
260
+ animeMusicVideo .setTitle (animeVideoNode .get ("title" ).asText ());
261
+ animeMusicVideo .setImageUrl (animeVideoNode .get ("video" ).get ("images" ).get ("maximum_image_url" ).asText ());
262
+ animeMusicVideo .setVideoUrl (animeVideoNode .get ("video" ).get ("embed_url" ).asText ());
263
+ newAnimeList .add (animeMusicVideo );
264
+ }
265
+
266
+ handler .post (() -> {
267
+ musicVideos .clear ();
268
+ musicVideos .addAll (newAnimeList );
269
+ Log .d ("HomeFragment" , "Number of anime in the newlist: " + newAnimeList .size ());
270
+ Log .d ("HomeFragment" , "Number of anime in the list: " + musicVideos .size ());
271
+ musicVideoAdapter .notifyDataSetChanged ();
272
+ });
273
+
274
+ } catch (IOException e ) {
275
+ e .printStackTrace ();
276
+ handler .post (() -> {
277
+ Toast .makeText (this , "Failed to fetch music videos" , Toast .LENGTH_SHORT ).show ();
278
+ });
279
+ }
280
+ });
188
281
}
189
282
private void updateFavoriteButton () {
190
283
if (favoritesManager .isFavorite (anime )) {
0 commit comments