├── sort_asc.png
├── sort_desc.png
├── GPM_Albums_sorted.png
├── GPM_Albums_default.png
├── LICENSE
├── README.md
└── google_play_music_album_sorter.user.js
/sort_asc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VipSaran/Google-Play-Music-Album-Sorter/HEAD/sort_asc.png
--------------------------------------------------------------------------------
/sort_desc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VipSaran/Google-Play-Music-Album-Sorter/HEAD/sort_desc.png
--------------------------------------------------------------------------------
/GPM_Albums_sorted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VipSaran/Google-Play-Music-Album-Sorter/HEAD/GPM_Albums_sorted.png
--------------------------------------------------------------------------------
/GPM_Albums_default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VipSaran/Google-Play-Music-Album-Sorter/HEAD/GPM_Albums_default.png
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 VipSaran
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | **Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
4 |
5 | - [Google-Play-Music-Album-Sorter](#google-play-music-album-sorter)
6 | - [Prerequisites](#prerequisites)
7 | - [Installation](#installation)
8 | - [Limitations](#limitations)
9 | - [To-Do](#to-do)
10 | - [Changelog](#changelog)
11 |
12 |
13 |
14 | # Google-Play-Music-Album-Sorter
15 |
16 | Greasemonkey/Tampermonkey UserScript for extending Google Play Music with album sorting functionality.
17 |
18 | Ascending and descending orders are supported, with last used being remembered.
19 |
20 | **Before:**
21 |
22 | 
23 |
24 | **After:**
25 |
26 | 
27 |
28 | ## Prerequisites
29 |
30 | To be able to employ the UserScript, your browser needs to have corresponding extensions installed:
31 |
32 | - Chrome: [Tampermonkey](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo)
33 | - Firefox: [Greasemonkey](https://addons.mozilla.org/en-US/firefox/addon/greasemonkey/)
34 |
35 |
36 | ## Installation
37 |
38 | Once your browser is equipped with appropriate extension, simply open [this link](https://github.com/VipSaran/Google-Play-Music-Album-Sorter/raw/master/google_play_music_album_sorter.user.js). The extension should recognize the script and offer you to install it.
39 |
40 |
41 | ## Limitations
42 |
43 | - works only on standalone "Albums" view
44 | - sorts only by album year
45 |
46 |
47 | ## To-Do
48 |
49 | - after sorting by year, also sort by name (in same order)
50 | - switch between year and name sorting
51 |
52 | ## Changelog
53 |
54 | 1.1.2
55 |
56 | - fix for parsing non-Albums sections
57 |
58 | 1.1.1
59 |
60 | - adapted to material design GPM
61 |
62 | 1.0.1
63 |
64 | - adapted to content div id change
65 |
--------------------------------------------------------------------------------
/google_play_music_album_sorter.user.js:
--------------------------------------------------------------------------------
1 | // ==UserScript==
2 | // @name Google Play Music Album Sorter
3 | // @description Greasemonkey/Tampermonkey UserScript for extending Google Play Music with album sorting functionality
4 | // @namespace http://github.com/VipSaran/Google-Play-Music-Album-Sorter
5 | // @updateURL https://github.com/VipSaran/Google-Play-Music-Album-Sorter/raw/master/google_play_music_album_sorter.user.js
6 | // @version 1.2.1
7 | // @author VipSaran
8 | // @require http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js
9 | // @resource sort_asc https://github.com/VipSaran/Google-Play-Music-Album-Sorter/raw/master/sort_asc.png
10 | // @resource sort_desc https://github.com/VipSaran/Google-Play-Music-Album-Sorter/raw/master/sort_desc.png
11 | // @grant GM_getResourceURL
12 | // @include http://play.google.com/music/listen*
13 | // @include https://play.google.com/music/listen*
14 | // @include http://music.google.com/music/listen*
15 | // @include https://music.google.com/music/listen*
16 | // @match http://play.google.com/music/listen*
17 | // @match https://play.google.com/music/listen*
18 | // @match http://music.google.com/music/listen*
19 | // @match https://music.google.com/music/listen*
20 | // @run-at document-end
21 | // ==/UserScript==
22 |
23 | var DEBUG = false;
24 |
25 | var $ = window.jQuery;
26 |
27 | function GooglePlayMusicAlbumSorter() {
28 | if (DEBUG) console.log('GooglePlayMusicAlbumSorter()');
29 | }
30 |
31 | GooglePlayMusicAlbumSorter.prototype.loadOrder = function () {
32 | if (DEBUG) console.log('GooglePlayMusicAlbumSorter.loadOrder()');
33 | return window.localStorage.getItem('order');
34 | };
35 |
36 | GooglePlayMusicAlbumSorter.prototype.saveOrder = function (order) {
37 | if (DEBUG) console.log('GooglePlayMusicAlbumSorter.saveOrder()');
38 |
39 | window.localStorage.setItem('order', order);
40 | };
41 |
42 | var sectionHeaderText = '';
43 | var sortingInProgress = false;
44 | var domModifiedTimeout;
45 | var domModifiedCallback = function () {
46 | if (DEBUG) console.log('domModifiedCallback()');
47 |
48 | if (domModifiedTimeout) {
49 | clearTimeout(domModifiedTimeout);
50 | }
51 |
52 | var laneContent = $('#music-content .lane-content');
53 | if (DEBUG) console.log('laneContent=', laneContent);
54 |
55 | var sectionHeader = $('.header');
56 | if (sectionHeader) {
57 | sortingInProgress = true;
58 |
59 | var sortOrder = sorter.loadOrder() || 'asc';
60 | if (DEBUG) console.log('sortOrder=', sortOrder);
61 |
62 | // if (DEBUG) console.log('$(#gpmas_sorter)=', $('#gpmas_sorter').html());
63 | if ($('#gpmas_sorter').html() === undefined) {
64 | sectionHeader.append('');
65 |
66 | $('#gpmas_sorter').click(function (event) {
67 | var currClass = $(this).attr('class');
68 | if (DEBUG) console.log('gpmas_sorter click', currClass);
69 |
70 | $(this).toggleClass('asc desc');
71 |
72 | currClass = $(this).attr('class');
73 | if (DEBUG) console.log('gpmas_sorter click', currClass);
74 |
75 | sorter.saveOrder(currClass);
76 |
77 | domModifiedCallback();
78 | });
79 | }
80 |
81 | var albums = $("div").find("[data-type='album']").filter(':not(.player-album)');
82 | if (DEBUG) console.log('albums=', albums);
83 |
84 | albums.sort(function (a, b) {
85 | var aYear = $(a).find("a.sub-title").html();
86 | var bYear = $(b).find("a.sub-title").html();
87 | return sortOrder === 'asc' ? aYear - bYear : bYear - aYear;
88 | });
89 |
90 | laneContent.children("[data-type='album']").fadeOut("fast").promise().done(function () {
91 | laneContent.empty();
92 |
93 | for (var i = 0; albums.length > 0; i++) {
94 | var album = albums.get(0);
95 | albums.splice(0, 1);
96 | laneContent.append(album);
97 | }
98 |
99 | laneContent.children("[data-type='album']").each(function (i) {
100 | $(this).delay(i * 50).fadeIn("fast");
101 | });
102 |
103 | sortingInProgress = false;
104 | });
105 | }
106 | };
107 |
108 | GooglePlayMusicAlbumSorter.prototype.init = function () {
109 | if (DEBUG) console.log('GooglePlayMusicAlbumSorter.init()');
110 |
111 | $('head').append(
112 | ''
117 | );
118 |
119 | // if (DEBUG) console.log($('#music-content .lane-content'));
120 | $('#music-content').bind("DOMNodeInserted", function (event) {
121 | if (DEBUG) console.log('DOMNodeInserted', event.target.nodeName);
122 |
123 | var element = $(event.target);
124 | if (!(element.hasClass('g-content') || element.hasClass('cluster'))) {
125 | return;
126 | }
127 |
128 | var sectionHeaderTitleText = $('.header .title').html();
129 | // if (DEBUG) console.log('sectionHeaderTitleText=', sectionHeaderTitleText);
130 | if (sectionHeaderTitleText !== 'Albums') {
131 | return;
132 | }
133 |
134 | if (domModifiedTimeout) {
135 | clearTimeout(domModifiedTimeout);
136 | }
137 | if (sortingInProgress) {
138 | return;
139 | }
140 | domModifiedTimeout = setTimeout(function () {
141 | domModifiedCallback();
142 | }, 500);
143 |
144 | });
145 | };
146 |
147 | var sorter = new GooglePlayMusicAlbumSorter();
148 |
149 | $(document).ready(function () {
150 | sorter.init();
151 | });
--------------------------------------------------------------------------------