OSDN Git Service

Eleven: Change playlist to the new layout, rip out dead code
[android-x86/packages-apps-Eleven.git] / src / com / cyngn / eleven / ui / activities / ProfileActivity.java
1 /*
2  * Copyright (C) 2012 Andrew Neal Licensed under the Apache License, Version 2.0
3  * (the "License"); you may not use this file except in compliance with the
4  * License. You may obtain a copy of the License at
5  * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
6  * or agreed to in writing, software distributed under the License is
7  * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
8  * KIND, either express or implied. See the License for the specific language
9  * governing permissions and limitations under the License.
10  */
11
12 package com.cyngn.eleven.ui.activities;
13
14 import android.app.ActionBar;
15 import android.app.Activity;
16 import android.app.SearchManager;
17 import android.content.Intent;
18 import android.content.pm.ActivityInfo;
19 import android.database.Cursor;
20 import android.graphics.Bitmap;
21 import android.net.Uri;
22 import android.os.Bundle;
23 import android.os.SystemClock;
24 import android.provider.MediaStore;
25 import android.support.v4.view.ViewPager;
26 import android.support.v4.view.ViewPager.OnPageChangeListener;
27 import android.view.Menu;
28 import android.view.MenuItem;
29 import android.view.View;
30
31 import com.cyngn.eleven.Config;
32 import com.cyngn.eleven.R;
33 import com.cyngn.eleven.adapters.PagerAdapter;
34 import com.cyngn.eleven.cache.ImageFetcher;
35 import com.cyngn.eleven.menu.PhotoSelectionDialog;
36 import com.cyngn.eleven.menu.PhotoSelectionDialog.ProfileType;
37 import com.cyngn.eleven.ui.fragments.profile.AlbumSongFragment;
38 import com.cyngn.eleven.ui.fragments.profile.ArtistAlbumFragment;
39 import com.cyngn.eleven.ui.fragments.profile.ArtistSongFragment;
40 import com.cyngn.eleven.ui.fragments.profile.GenreSongFragment;
41 import com.cyngn.eleven.ui.fragments.profile.LastAddedFragment;
42 import com.cyngn.eleven.utils.ApolloUtils;
43 import com.cyngn.eleven.utils.MusicUtils;
44 import com.cyngn.eleven.utils.NavUtils;
45 import com.cyngn.eleven.utils.PreferenceUtils;
46 import com.cyngn.eleven.utils.SortOrder;
47 import com.cyngn.eleven.widgets.ProfileTabCarousel;
48 import com.cyngn.eleven.widgets.ProfileTabCarousel.Listener;
49
50 /**
51  * The {@link Activity} is used to display the data for specific
52  * artists, albums, playlists, and genres. This class is only used on phones.
53  * 
54  * @author Andrew Neal (andrewdneal@gmail.com)
55  */
56 public class ProfileActivity extends SlidingPanelActivity implements OnPageChangeListener, Listener {
57
58     private static final int NEW_PHOTO = 1;
59
60     /**
61      * The Bundle to pass into the Fragments
62      */
63     private Bundle mArguments;
64
65     /**
66      * View pager
67      */
68     private ViewPager mViewPager;
69
70     /**
71      * Pager adpater
72      */
73     private PagerAdapter mPagerAdapter;
74
75     /**
76      * Profile header carousel
77      */
78     private ProfileTabCarousel mTabCarousel;
79
80     /**
81      * MIME type of the profile
82      */
83     private String mType;
84
85     /**
86      * Artist name passed into the class
87      */
88     private String mArtistName;
89
90     /**
91      * The main profile title
92      */
93     private String mProfileName;
94
95     /**
96      * Image cache
97      */
98     private ImageFetcher mImageFetcher;
99
100     private PreferenceUtils mPreferences;
101
102     /**
103      * {@inheritDoc}
104      */
105     @Override
106     public void onCreate(final Bundle savedInstanceState) {
107         mTargetNavigatePanel = Panel.Browse;
108         super.onCreate(savedInstanceState);
109         // Temporay until I can work out a nice landscape layout
110         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
111
112         // Get the preferences
113         mPreferences = PreferenceUtils.getInstance(this);
114
115         // Initialze the image fetcher
116         mImageFetcher = ApolloUtils.getImageFetcher(this);
117
118         // Initialize the Bundle
119         mArguments = savedInstanceState != null ? savedInstanceState : getIntent().getExtras();
120         // Get the MIME type
121         mType = mArguments.getString(Config.MIME_TYPE);
122         // Get the profile title
123         mProfileName = mArguments.getString(Config.NAME);
124         // Get the artist name
125         if (isArtist() || isAlbum()) {
126             mArtistName = mArguments.getString(Config.ARTIST_NAME);
127         }
128
129         // Initialize the pager adapter
130         mPagerAdapter = new PagerAdapter(this);
131
132         // Initialze the carousel
133         mTabCarousel = (ProfileTabCarousel)findViewById(R.id.acivity_profile_base_tab_carousel);
134         mTabCarousel.reset();
135         mTabCarousel.getPhoto().setOnClickListener(new View.OnClickListener() {
136
137             @Override
138             public void onClick(final View v) {
139                 ProfileType profileType;
140                 if (isArtist()) {
141                     profileType = ProfileType.ARTIST;
142                 } else if (isAlbum()) {
143                     profileType = ProfileType.ALBUM;
144                 } else {
145                     profileType = ProfileType.OTHER;
146                 }
147                 PhotoSelectionDialog.newInstance(isArtist() ? mArtistName : mProfileName,
148                         profileType).show(getSupportFragmentManager(), "PhotoSelectionDialog");
149             }
150         });
151         // Set up the action bar
152         final ActionBar actionBar = getActionBar();
153         actionBar.setIcon(R.drawable.ic_action_back);
154         actionBar.setHomeButtonEnabled(true);
155
156         /* Set up the artist profile */
157         if (isArtist()) {
158             // Add the carousel images
159             mTabCarousel.setArtistProfileHeader(this, mArtistName);
160
161             // Artist profile fragments
162             mPagerAdapter.add(ArtistSongFragment.class, mArguments);
163             mPagerAdapter.add(ArtistAlbumFragment.class, mArguments);
164
165             // Action bar title
166             getActionBar().setTitle(mArtistName);
167
168         } else
169         // Set up the album profile
170         if (isAlbum()) {
171             // Add the carousel images
172             mTabCarousel.setAlbumProfileHeader(this, mProfileName, mArtistName);
173
174             // Album profile fragments
175             mPagerAdapter.add(AlbumSongFragment.class, mArguments);
176
177             // Action bar title = album name
178             getActionBar().setTitle(mProfileName);
179             // Action bar subtitle = year released
180             getActionBar().setSubtitle(mArguments.getString(Config.ALBUM_YEAR));
181         } else
182         // Set up the last added profile
183         if (isLastAdded()) {
184             // Add the carousel images
185             mTabCarousel.setPlaylistOrGenreProfileHeader(this, mProfileName);
186
187             // Last added fragment
188             mPagerAdapter.add(LastAddedFragment.class, null);
189
190             // Action bar title = Last added
191             getActionBar().setTitle(mProfileName);
192         } else
193         // Set up the genre profile
194         if (isGenre()) {
195             // Add the carousel images
196             mTabCarousel.setPlaylistOrGenreProfileHeader(this, mProfileName);
197
198             // Genre profile fragments
199             mPagerAdapter.add(GenreSongFragment.class, mArguments);
200
201             // Action bar title = playlist name
202             getActionBar().setTitle(mProfileName);
203         }
204
205         // Initialize the ViewPager
206         mViewPager = (ViewPager)findViewById(R.id.acivity_profile_base_pager);
207         // Attch the adapter
208         mViewPager.setAdapter(mPagerAdapter);
209         // Offscreen limit
210         mViewPager.setOffscreenPageLimit(mPagerAdapter.getCount() - 1);
211         // Attach the page change listener
212         mViewPager.setOnPageChangeListener(this);
213         // Attach the carousel listener
214         mTabCarousel.setListener(this);
215     }
216
217     @Override
218     protected int getLayoutToInflate() {
219         return R.layout.activity_profile_base;
220     }
221
222     /**
223      * {@inheritDoc}
224      */
225     @Override
226     protected void onPause() {
227         super.onPause();
228         mImageFetcher.flush();
229     }
230
231     /**
232      * {@inheritDoc}
233      */
234     @Override
235     public boolean onPrepareOptionsMenu(final Menu menu) {
236         // Set the shuffle all title to "play all" if a playlist.
237         final MenuItem shuffle = menu.findItem(R.id.menu_shuffle);
238         String title = null;
239         if (isLastAdded()) {
240             title = getString(R.string.menu_play_all);
241         } else {
242             title = getString(R.string.menu_shuffle);
243         }
244         shuffle.setTitle(title);
245         return super.onPrepareOptionsMenu(menu);
246     }
247
248     /**
249      * {@inheritDoc}
250      */
251     @Override
252     public boolean onCreateOptionsMenu(final Menu menu) {
253         // Shuffle
254         getMenuInflater().inflate(R.menu.shuffle, menu);
255         // Sort orders
256         if (isArtistSongPage()) {
257             getMenuInflater().inflate(R.menu.artist_song_sort_by, menu);
258         } else if (isArtistAlbumPage()) {
259             getMenuInflater().inflate(R.menu.artist_album_sort_by, menu);
260         } else if (isAlbum()) {
261             getMenuInflater().inflate(R.menu.album_song_sort_by, menu);
262         }
263         return super.onCreateOptionsMenu(menu);
264     }
265
266     /**
267      * {@inheritDoc}
268      */
269     @Override
270     public boolean onOptionsItemSelected(final MenuItem item) {
271         switch (item.getItemId()) {
272             case android.R.id.home:
273                 // If an album profile, go up to the artist profile
274                 if (isAlbum()) {
275                     NavUtils.openArtistProfile(this, mArtistName);
276                     finish();
277                 } else {
278                     // Otherwise just go back
279                     goBack();
280                 }
281                 return true;
282             case R.id.menu_shuffle: {
283                 final long id = mArguments.getLong(Config.ID);
284                 long[] list = null;
285                 if (isArtist()) {
286                     list = MusicUtils.getSongListForArtist(this, id);
287                 } else if (isAlbum()) {
288                     list = MusicUtils.getSongListForAlbum(this, id);
289                 } else if (isGenre()) {
290                     list = MusicUtils.getSongListForGenre(this, id);
291                 }
292                 if (isLastAdded()) {
293                     MusicUtils.playLastAdded(this);
294                 } else {
295                     if (list != null && list.length > 0) {
296                         MusicUtils.playAll(this, list, 0, true);
297                     }
298                 }
299                 return true;
300             }
301             case R.id.menu_sort_by_az:
302                 if (isArtistSongPage()) {
303                     mPreferences.setArtistSongSortOrder(SortOrder.ArtistSongSortOrder.SONG_A_Z);
304                     getArtistSongFragment().refresh();
305                 } else if (isArtistAlbumPage()) {
306                     mPreferences.setArtistAlbumSortOrder(SortOrder.ArtistAlbumSortOrder.ALBUM_A_Z);
307                     getArtistAlbumFragment().refresh();
308                 } else {
309                     mPreferences.setAlbumSongSortOrder(SortOrder.AlbumSongSortOrder.SONG_A_Z);
310                     getAlbumSongFragment().refresh();
311                 }
312                 return true;
313             case R.id.menu_sort_by_za:
314                 if (isArtistSongPage()) {
315                     mPreferences.setArtistSongSortOrder(SortOrder.ArtistSongSortOrder.SONG_Z_A);
316                     getArtistSongFragment().refresh();
317                 } else if (isArtistAlbumPage()) {
318                     mPreferences.setArtistAlbumSortOrder(SortOrder.ArtistAlbumSortOrder.ALBUM_Z_A);
319                     getArtistAlbumFragment().refresh();
320                 } else {
321                     mPreferences.setAlbumSongSortOrder(SortOrder.AlbumSongSortOrder.SONG_Z_A);
322                     getAlbumSongFragment().refresh();
323                 }
324                 return true;
325             case R.id.menu_sort_by_album:
326                 if (isArtistSongPage()) {
327                     mPreferences.setArtistSongSortOrder(SortOrder.ArtistSongSortOrder.SONG_ALBUM);
328                     getArtistSongFragment().refresh();
329                 }
330                 return true;
331             case R.id.menu_sort_by_year:
332                 if (isArtistSongPage()) {
333                     mPreferences.setArtistSongSortOrder(SortOrder.ArtistSongSortOrder.SONG_YEAR);
334                     getArtistSongFragment().refresh();
335                 } else if (isArtistAlbumPage()) {
336                     mPreferences.setArtistAlbumSortOrder(SortOrder.ArtistAlbumSortOrder.ALBUM_YEAR);
337                     getArtistAlbumFragment().refresh();
338                 }
339                 return true;
340             case R.id.menu_sort_by_duration:
341                 if (isArtistSongPage()) {
342                     mPreferences
343                             .setArtistSongSortOrder(SortOrder.ArtistSongSortOrder.SONG_DURATION);
344                     getArtistSongFragment().refresh();
345                 } else {
346                     mPreferences.setAlbumSongSortOrder(SortOrder.AlbumSongSortOrder.SONG_DURATION);
347                     getAlbumSongFragment().refresh();
348                 }
349                 return true;
350             case R.id.menu_sort_by_date_added:
351                 if (isArtistSongPage()) {
352                     mPreferences.setArtistSongSortOrder(SortOrder.ArtistSongSortOrder.SONG_DATE);
353                     getArtistSongFragment().refresh();
354                 }
355                 return true;
356             case R.id.menu_sort_by_track_list:
357                 mPreferences.setAlbumSongSortOrder(SortOrder.AlbumSongSortOrder.SONG_TRACK_LIST);
358                 getAlbumSongFragment().refresh();
359                 return true;
360             case R.id.menu_sort_by_filename:
361                 if(isArtistSongPage()) {
362                     mPreferences.setArtistSortOrder(SortOrder.ArtistSongSortOrder.SONG_FILENAME);
363                     getArtistSongFragment().refresh();
364                 }
365                 else {
366                     mPreferences.setAlbumSongSortOrder(SortOrder.AlbumSongSortOrder.SONG_FILENAME);
367                     getAlbumSongFragment().refresh();
368                 }
369                 return true;
370             default:
371                 break;
372         }
373         return super.onOptionsItemSelected(item);
374     }
375
376     /**
377      * {@inheritDoc}
378      */
379     @Override
380     protected void onSaveInstanceState(final Bundle outState) {
381         super.onSaveInstanceState(outState);
382         outState.putAll(mArguments);
383     }
384
385     /**
386      * {@inheritDoc}
387      */
388     @Override
389     public void onBackPressed() {
390         super.onBackPressed();
391     }
392
393     /**
394      * {@inheritDoc}
395      */
396     @Override
397     public void onPageScrolled(final int position, final float positionOffset,
398             final int positionOffsetPixels) {
399         if (mViewPager.isFakeDragging()) {
400             return;
401         }
402
403         final int scrollToX = (int)((position + positionOffset) * mTabCarousel
404                 .getAllowedHorizontalScrollLength());
405         mTabCarousel.scrollTo(scrollToX, 0);
406     }
407
408     /**
409      * {@inheritDoc}
410      */
411     @Override
412     public void onPageSelected(final int position) {
413         mTabCarousel.setCurrentTab(position);
414     }
415
416     /**
417      * {@inheritDoc}
418      */
419     @Override
420     public void onPageScrollStateChanged(final int state) {
421         if (state == ViewPager.SCROLL_STATE_IDLE) {
422             mTabCarousel.restoreYCoordinate(75, mViewPager.getCurrentItem());
423         }
424     }
425
426     /**
427      * {@inheritDoc}
428      */
429     @Override
430     public void onTouchDown() {
431         if (!mViewPager.isFakeDragging()) {
432             mViewPager.beginFakeDrag();
433         }
434     }
435
436     /**
437      * {@inheritDoc}
438      */
439     @Override
440     public void onTouchUp() {
441         if (mViewPager.isFakeDragging()) {
442             mViewPager.endFakeDrag();
443         }
444     }
445
446     /**
447      * {@inheritDoc}
448      */
449     @Override
450     public void onScrollChanged(final int l, final int t, final int oldl, final int oldt) {
451         if (mViewPager.isFakeDragging()) {
452             mViewPager.fakeDragBy(oldl - l);
453         }
454     }
455
456     /**
457      * {@inheritDoc}
458      */
459     @Override
460     public void onTabSelected(final int position) {
461         mViewPager.setCurrentItem(position);
462     }
463
464     /**
465      * {@inheritDoc}
466      */
467     @Override
468     protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
469         super.onActivityResult(requestCode, resultCode, data);
470         if (requestCode == NEW_PHOTO) {
471             if (resultCode == RESULT_OK) {
472                 final Uri selectedImage = data.getData();
473                 final String[] filePathColumn = {
474                     MediaStore.Images.Media.DATA
475                 };
476
477                 Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null,
478                         null, null);
479                 if (cursor != null && cursor.moveToFirst()) {
480                     final int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
481                     final String picturePath = cursor.getString(columnIndex);
482                     cursor.close();
483                     cursor = null;
484
485                     String key = mProfileName;
486                     if (isArtist()) {
487                         key = mArtistName;
488                     } else if (isAlbum()) {
489                         key = ImageFetcher.generateAlbumCacheKey(mProfileName, mArtistName);
490                     }
491
492                     final Bitmap bitmap = ImageFetcher.decodeSampledBitmapFromFile(picturePath);
493                     mImageFetcher.addBitmapToCache(key, bitmap);
494                     if (isAlbum()) {
495                         mTabCarousel.getAlbumArt().setImageBitmap(bitmap);
496                     } else {
497                         mTabCarousel.getPhoto().setImageBitmap(bitmap);
498                     }
499                 }
500             } else {
501                 selectOldPhoto();
502             }
503         }
504     }
505
506     /**
507      * Starts an activity for result that returns an image from the Gallery.
508      */
509     public void selectNewPhoto() {
510         // First remove the old image
511         removeFromCache();
512         // Now open the gallery
513         final Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
514         intent.setType("image/*");
515         startActivityForResult(intent, NEW_PHOTO);
516     }
517
518     /**
519      * Fetchs for the artist or album art, other wise sets the default header
520      * image.
521      */
522     public void selectOldPhoto() {
523         // First remove the old image
524         removeFromCache();
525         // Apply the old photo
526         if (isArtist()) {
527             mTabCarousel.setArtistProfileHeader(this, mArtistName);
528         } else if (isAlbum()) {
529             mTabCarousel.setAlbumProfileHeader(this, mProfileName, mArtistName);
530         } else {
531             mTabCarousel.setPlaylistOrGenreProfileHeader(this, mProfileName);
532         }
533     }
534
535     /**
536      * When the user chooses {@code #selectOldPhoto()} while viewing an album
537      * profile, the image is, most likely, reverted back to the locally found
538      * artwork. This is specifically for fetching the image from Last.fm.
539      */
540     public void fetchAlbumArt() {
541         // First remove the old image
542         removeFromCache();
543         // Fetch for the artwork
544         mTabCarousel.fetchAlbumPhoto(this, mProfileName, mArtistName);
545     }
546
547     /**
548      * Searches Google for the artist or album
549      */
550     public void googleSearch() {
551         String query = mProfileName;
552         if (isArtist()) {
553             query = mArtistName;
554         } else if (isAlbum()) {
555             query = mProfileName + " " + mArtistName;
556         }
557         final Intent googleSearch = new Intent(Intent.ACTION_WEB_SEARCH);
558         googleSearch.putExtra(SearchManager.QUERY, query);
559         startActivity(googleSearch);
560     }
561
562     /**
563      * Removes the header image from the cache.
564      */
565     private void removeFromCache() {
566         String key = mProfileName;
567         if (isArtist()) {
568             key = mArtistName;
569         } else if (isAlbum()) {
570             key = ImageFetcher.generateAlbumCacheKey(mProfileName, mArtistName);
571         }
572         mImageFetcher.removeFromCache(key);
573         // Give the disk cache a little time before requesting a new image.
574         SystemClock.sleep(80);
575     }
576
577     /**
578      * Finishes the activity and overrides the default animation.
579      */
580     private void goBack() {
581         finish();
582     }
583
584     /**
585      * @return True if the MIME type is vnd.android.cursor.dir/artists, false
586      *         otherwise.
587      */
588     private final boolean isArtist() {
589         return mType.equals(MediaStore.Audio.Artists.CONTENT_TYPE);
590     }
591
592     /**
593      * @return True if the MIME type is vnd.android.cursor.dir/albums, false
594      *         otherwise.
595      */
596     private final boolean isAlbum() {
597         return mType.equals(MediaStore.Audio.Albums.CONTENT_TYPE);
598     }
599
600     /**
601      * @return True if the MIME type is vnd.android.cursor.dir/gere, false
602      *         otherwise.
603      */
604     private final boolean isGenre() {
605         return mType.equals(MediaStore.Audio.Genres.CONTENT_TYPE);
606     }
607
608     /**
609      * @return True if the MIME type is "LastAdded", false otherwise.
610      */
611     private final boolean isLastAdded() {
612         return mType.equals(getString(R.string.playlist_last_added));
613     }
614
615     private boolean isArtistSongPage() {
616         return isArtist() && mViewPager.getCurrentItem() == 0;
617     }
618
619     private boolean isArtistAlbumPage() {
620         return isArtist() && mViewPager.getCurrentItem() == 1;
621     }
622
623     private ArtistSongFragment getArtistSongFragment() {
624         return (ArtistSongFragment)mPagerAdapter.getFragment(0);
625     }
626
627     private ArtistAlbumFragment getArtistAlbumFragment() {
628         return (ArtistAlbumFragment)mPagerAdapter.getFragment(1);
629     }
630
631     private AlbumSongFragment getAlbumSongFragment() {
632         return (AlbumSongFragment)mPagerAdapter.getFragment(0);
633     }
634 }