/** * ShareManager.js * Minimal share manager - only basic share functionality. * Social fission features have been removed in monetization-lite. */ class ShareManager { constructor() { // Default share content this._shareContent = { title: '坦克大战 - 一起来战斗吧!', imageUrl: '', query: '', }; // Register share menu and callback ONCE at startup. // The callback reads this._shareContent dynamically so it always // returns the latest share data without needing re-registration. try { if (typeof wx !== 'undefined') { if (wx.showShareMenu) { wx.showShareMenu({ withShareTicket: true, menus: ['shareAppMessage'], }); } if (wx.onShareAppMessage) { wx.onShareAppMessage(() => { console.log('[ShareManager] onShareAppMessage callback, query:', this._shareContent.query); return { title: this._shareContent.title || '坦克大战 - 一起来战斗吧!', imageUrl: this._shareContent.imageUrl || '', query: this._shareContent.query || '', }; }); } } } catch (e) { console.warn('[ShareManager] constructor share setup failed:', e); } } /** * Update open data for friend ranking. * @param {number} score * @param {number} level */ updateOpenData(score, level) { try { if (typeof wx !== 'undefined' && wx.setUserCloudStorage) { wx.setUserCloudStorage({ KVDataList: [ { key: 'score', value: String(score) }, { key: 'level', value: String(level) }, ], }); } } catch (e) { console.warn('[ShareManager] updateOpenData failed:', e); } } /** * Re-register the onShareAppMessage callback so the latest * this._shareContent is captured. Called internally whenever * share content changes. */ _refreshShareCallback() { try { if (typeof wx !== 'undefined' && wx.onShareAppMessage) { wx.onShareAppMessage(() => { console.log('[ShareManager] onShareAppMessage callback fired, query:', this._shareContent.query); return { title: this._shareContent.title || '坦克大战 - 一起来战斗吧!', imageUrl: this._shareContent.imageUrl || '', query: this._shareContent.query || '', }; }); } } catch (e) { console.warn('[ShareManager] _refreshShareCallback failed:', e); } } /** * Set share content for the passive share callback (right-corner ··· menu). * Also re-registers the onShareAppMessage callback to guarantee the * latest content is used when the user taps the share button. * @param {object} opts - { title, imageUrl, query } */ setShareContent(opts) { this._shareContent = opts || {}; console.log('[ShareManager] Share content updated:', JSON.stringify(this._shareContent)); // Re-register callback to ensure WeChat picks up the new content this._refreshShareCallback(); } /** * Trigger a share action (e.g. team invite). * MUST be called within a user-initiated touch event call stack so that * wx.shareAppMessage() is allowed by WeChat policy. * Also updates the passive share callback as a fallback for the ··· menu. * @param {object} opts - { title, imageUrl, query } */ triggerShare(opts) { const data = opts || {}; // Update passive share callback (right-corner ··· menu fallback) this.setShareContent(data); // Directly invoke wx.shareAppMessage() to open the friend-picker panel. // This is permitted because triggerShare is called from a touchstart handler. try { if (typeof wx !== 'undefined' && wx.shareAppMessage) { console.log('[ShareManager] Calling wx.shareAppMessage with query:', data.query); wx.shareAppMessage({ title: data.title || '', imageUrl: data.imageUrl || '', query: data.query || '', }); } } catch (e) { console.warn('[ShareManager] wx.shareAppMessage failed, falling back to toast:', e); // Fallback: prompt user to use the ··· menu try { if (typeof wx !== 'undefined' && wx.showToast) { wx.showToast({ title: '请点击右上角「···」转发给好友', icon: 'none', duration: 2500, }); } } catch (e2) { console.warn('[ShareManager] triggerShare fallback failed:', e2); } } } /** * Reset share content to default (clear team invite data). * Called when leaving the team room. */ resetShareContent() { this._shareContent = { title: '坦克大战 - 一起来战斗吧!', imageUrl: '', query: '', }; console.log('[ShareManager] Share content reset to default'); this._refreshShareCallback(); } /** * Share a challenge to friends. * Sets the share content and prompts the user to share via the menu. * @param {number} level * @param {number} score */ shareChallenge(level, score) { this.setShareContent({ title: `我在坦克大战第${level}关拿了${score}分!你能超过我吗?`, imageUrl: '', query: '', }); try { if (typeof wx !== 'undefined' && wx.showToast) { wx.showToast({ title: '请点击右上角「···」分享给好友', icon: 'none', duration: 2500, }); } } catch (e) { console.warn('[ShareManager] shareChallenge failed:', e); } } } module.exports = ShareManager;