PageSourceSearch

https://www.delsinrecords.com/scripts/favorites.js?1591075292

js delsinrecords.com collected 2026-09-25 18:40:43 UTC 6,732 bytes, 215 lines download raw bytes

1// Favorites module — localStorage for all, DB sync for logged-in users
2var Favorites = (function() {
3    var STORAGE_KEY = 'nmw_favorites';
4    var _list = []; // array of release IDs (integers)
5    var _synced = false;
6    var _iconClass = (typeof shop !== 'undefined' && shop.b2b) ? 'fa-star' : 'fa-heart';
7
8    function _save() {
9        try {
10            localStorage.setItem(STORAGE_KEY, JSON.stringify(_list));
11        } catch(e) {}
12    }
13
14    function _load() {
15        try {
16            var stored = localStorage.getItem(STORAGE_KEY);
17            _list = stored ? JSON.parse(stored) : [];
18            if (!Array.isArray(_list)) _list = [];
19        } catch(e) {
20            _list = [];
21        }
22    }
23
24    function _isLoggedIn() {
25        try {
26            var c = getCookie('login');
27            if (c) {
28                var d = JSON.parse(c);
29                return d && d.idxFrontUser;
30            }
31        } catch(e) {}
32        return false;
33    }
34
35    function _getReleaseId($el) {
36        var releaseId = null;
37        // Try from shopitem ID
38        var id = $el.attr('id');
39        if (id && id.indexOf('shopitem') === 0) {
40            releaseId = id.replace('shopitem', '');
41        }
42        if (!releaseId) {
43            // Try from release_id links
44            var $link = $el.find('a[href*="release_id="]');
45            if ($link.length) {
46                var match = $link.attr('href').match(/release_id=(\d+)/);
47                if (match) releaseId = match[1];
48            }
49        }
50        if (!releaseId) {
51            // Try from addCart onclick
52            var $cart = $el.find('[onclick*="addCart"]');
53            if ($cart.length) {
54                var cartMatch = $cart.attr('onclick').match(/addCart\('[^']*','(\d+)'\)/);
55                if (cartMatch) releaseId = cartMatch[1];
56            }
57        }
58        return releaseId;
59    }
60
61    function _injectButtons() {
62        var _btnHtml = function(releaseId) {
63            return '<span class="favorite-btn" data-release="' + releaseId + '" data-ajax="no-go" title="Favorite"><i class="far ' + _iconClass + '"></i></span>';
64        };
65
66        // List view: .wishlist-item placeholders with data-release attribute
67        $('.wishlist-item[data-release]').each(function() {
68            if ($(this).find('.favorite-btn').length > 0) return;
69            var releaseId = $(this).data('release');
70            if (!releaseId) return;
71            $(this).html(_btnHtml(releaseId));
72        });
73
74        // Grid view: .shopcol items with shopitem ID (top-level grid cards)
75        $('.shopcol[id^="shopitem"]').each(function() {
76            if ($(this).find('.favorite-btn').length > 0) return;
77            var releaseId = _getReleaseId($(this));
78            if (!releaseId) return;
79            var $firstLink = $(this).find('a').first();
80            if ($firstLink.length) {
81                $('<div class="favorite-row">' + _btnHtml(releaseId) + '</div>').insertAfter($firstLink);
82            } else {
83                $(this).prepend('<div class="favorite-row">' + _btnHtml(releaseId) + '</div>');
84            }
85        });
86    }
87
88    function _updateUI() {
89        _injectButtons();
90        $('.favorite-btn').each(function() {
91            var releaseId = parseInt($(this).data('release'));
92            if (_list.indexOf(releaseId) > -1) {
93                $(this).addClass('is-favorite');
94                $(this).find('i').removeClass('far').addClass('fas');
95            } else {
96                $(this).removeClass('is-favorite');
97                $(this).find('i').removeClass('fas').addClass('far');
98            }
99        });
100        // Update favorites count in menu
101        var count = _list.length;
102        $('.favorites-count').text(count > 0 ? '(' + count + ')' : '');
103        if (count > 0) {
104            $('.favorites-count').show();
105            $('.favorites-count').closest('a').find('i.fa-heart').removeClass('far').addClass('fas');
106        } else {
107            $('.favorites-count').hide();
108            $('.favorites-count').closest('a').find('i.fa-heart').removeClass('fas').addClass('far');
109        }
110    }
111
112    function toggle(releaseId) {
113        releaseId = parseInt(releaseId);
114        var idx = _list.indexOf(releaseId);
115        if (idx > -1) {
116            _list.splice(idx, 1);
117        } else {
118            _list.push(releaseId);
119        }
120        _save();
121        _updateUI();
122
123        // If logged in, also sync to DB
124        if (_isLoggedIn()) {
125            $.post('/ajax_favorites.php', {
126                action: 'toggle',
127                idxRelease: releaseId
128            });
129        }
130    }
131
132    function isFavorite(releaseId) {
133        return _list.indexOf(parseInt(releaseId)) > -1;
134    }
135
136    function getList() {
137        return _list.slice();
138    }
139
140    function syncOnLogin() {
141        if (!_isLoggedIn()) return;
142        if (_synced) return;
143        _synced = true;
144
145        // Send local favorites to DB, get merged list back
146        $.post('/ajax_favorites.php', {
147            action: 'sync',
148            releases: JSON.stringify(_list)
149        }, function(data) {
150            if (data && data.success && data.favorites) {
151                _list = data.favorites;
152                _save();
153                _updateUI();
154            }
155        }, 'JSON');
156    }
157
158    function init() {
159        _load();
160
161        // Delegate click handler for favorite buttons
162        $(document).on('click', '.favorite-btn', function(e) {
163            e.preventDefault();
164            e.stopPropagation();
165            var releaseId = $(this).data('release');
166            toggle(releaseId);
167        });
168
169        // If logged in, sync with DB
170        if (_isLoggedIn()) {
171            syncOnLogin();
172        } else {
173            _updateUI();
174        }
175
176    }
177
178    function clearAll(callback) {
179        var toRemove = _list.slice();
180        _list = [];
181        _save();
182        _updateUI();
183
184        if (_isLoggedIn() && toRemove.length > 0) {
185            // Toggle each favorite off in the DB
186            var pending = toRemove.length;
187            function done() {
188                pending--;
189                if (pending <= 0 && callback) callback();
190            }
191            toRemove.forEach(function(releaseId) {
192                $.post('/ajax_favorites.php', {
193                    action: 'toggle',
194                    idxRelease: releaseId
195                }).always(done);
196            });
197        } else {
198            if (callback) callback();
199        }
200    }
201
202    return {
203        init: init,
204        toggle: toggle,
205        isFavorite: isFavorite,
206        getList: getList,
207        syncOnLogin: syncOnLogin,
208        updateUI: _updateUI,
209        clearAll: clearAll
210    };
211})();
212
213$(document).ready(function() {
214    Favorites.init();
215});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.