Publish Vulpes Preview 15 sources for desktop, Android and Tundra

Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
OverSu 2026-09-30 23:13:03 +02:00
commit b38dea0597
25901 changed files with 9982925 additions and 369 deletions

View file

@ -0,0 +1,2 @@
;'use strict';function DtmfTone(tone,short,serviceId){this.tone=tone;this.short=short;this.serviceId=serviceId;this.timer=0;}
DtmfTone.kShortToneLength=120;DtmfTone.prototype={play:function dt_play(){clearTimeout(this.timer);navigator.mozTelephony.stopTone(this.serviceId);navigator.mozTelephony.startTone(this.tone,this.serviceId);if(this.short){this.timer=window.setTimeout(function dt_stopTone(serviceId){navigator.mozTelephony.stopTone(serviceId);},DtmfTone.kShortToneLength,this.serviceId);}},stop:function dt_stop(){clearTimeout(this.timer);navigator.mozTelephony.stopTone(this.serviceId);}};

View file

@ -0,0 +1,134 @@
'use strict';
/* globals ConfirmDialog, LazyLoader */
/* exported TelephonyMessages */
var TelephonyMessages = {
/**
* Constants for what message to display when we get a bad number error.
* Depends on the situation.
*/
// Display the regular "invalid number" message, as this is a regular call.
REGULAR_CALL: 0,
// We have no network and/or no SIM, so we can only make emergency calls.
// Display the "no network" message.
NO_NETWORK: 1,
// We are making a call from an emergency call view, so calls can only be
// placed to emergency and ICE numbers. Display the "not an emergency number"
// message.
EMERGENCY_ONLY: 2,
displayMessage: function(message, number) {
var dialogTitle, dialogBody;
switch (message) {
case 'BadNumber':
dialogTitle = 'invalidNumberToDialTitle';
dialogBody = 'invalidNumberToDialMessage';
break;
case 'FlightMode':
dialogTitle = 'callAirplaneModeTitle';
dialogBody = 'callAirplaneModeMessage';
break;
case 'NoNetwork':
dialogTitle = 'emergencyDialogTitle';
dialogBody = 'emergencyDialogBodyBadNumber';
break;
case 'DeviceNotAccepted':
dialogTitle = 'emergencyDialogTitle';
dialogBody = 'emergencyDialogBodyDeviceNotAccepted';
break;
case 'UnableToCall':
dialogTitle = 'unableToCallTitle';
dialogBody = 'unableToCallMessage';
break;
case 'NumberIsBusy':
dialogTitle = 'numberIsBusyTitle';
dialogBody = 'numberIsBusyMessage';
break;
case 'FixedDialingNumbers':
dialogTitle = 'fdnIsActiveTitle';
dialogBody = 'fdnIsActiveMessage';
break;
case 'OtherConnectionInUse':
dialogTitle = 'otherConnectionInUseTitle';
dialogBody = 'otherConnectionInUseMessage';
break;
case 'OperatorDeterminedBarring':
dialogTitle = 'unableToCallTitle';
dialogBody = 'callBarredByTheOperatorMessage';
break;
case 'EmergencyCallOnly':
dialogTitle = 'emergency-call-only';
dialogBody = 'emergency-call-error';
break;
default:
console.error('Invalid message argument'); // Should never happen
return;
}
LazyLoader.load(['/shared/style/confirm.css',
'/shared/js/confirm.js',
document.getElementById('confirmation-message')],
function() {
ConfirmDialog.show(
dialogTitle,
{id: dialogBody, args: {number: number}},
{
title: 'emergencyDialogBtnOk', // Just 'ok' would be better.
callback: function() {
ConfirmDialog.hide();
}
}
);
}
);
},
handleDisconnect: function(reason, number, emergencyOptions) {
if (reason === 'NormalCallClearing') {
return;
}
this.handleError(reason + 'Error', number, emergencyOptions);
},
handleError: function(errorName, number, emergencyOptions) {
// We ignore this error because some networks generate this with
// STK CallControl when calling Voicemail pilots (e.g. TMobile)
if (errorName === 'ModifiedDialError') {
console.log('ModifiedDialError');
return;
}
if (errorName === 'BadNumberError') {
if (emergencyOptions === this.REGULAR_CALL) {
this.displayMessage('BadNumber');
} else if (emergencyOptions === this.NO_NETWORK) {
this.displayMessage('NoNetwork');
} else if (emergencyOptions === this.EMERGENCY_ONLY) {
this.displayMessage('EmergencyCallOnly', number);
} else {
console.error('Unexpected emergency options: ' + emergencyOptions);
}
} else if (errorName === 'DeviceNotAcceptedError') {
this.displayMessage('DeviceNotAccepted');
} else if (errorName === 'RadioNotAvailable') {
this.displayMessage('FlightMode');
} else if (errorName === 'BusyError') {
this.displayMessage('NumberIsBusy');
} else if (errorName === 'FDNBlockedError' ||
errorName === 'FdnCheckFailure') {
this.displayMessage('FixedDialingNumbers', number);
} else if (errorName === 'OtherConnectionInUse') {
this.displayMessage('OtherConnectionInUse');
} else if (errorName === 'OperatorDeterminedBarringError') {
this.displayMessage('OperatorDeterminedBarring');
} else {
// If the call failed for some other reason we should still
// display something to the user. See bug 846403.
console.error('Unexpected error: ', errorName);
this.displayMessage('UnableToCall');
}
},
};

View file

@ -0,0 +1,9 @@
;'use strict';const kMasterVolume=0.5;const kToneVolume=0.7;const kShortPressDuration=0.15;const kAttackDuration=0.025;const kDecayDuration=0.025;const kReleaseDuration=0.05;var TonePlayer={_audioContext:null,_channel:null,_gainNode:null,_playingNodes:[],_maybeTrashAudio:null,_initialized:false,init:function tp_init(channel){var telephony=navigator.mozTelephony;this._reset();this._channel=channel;this._maybeTrashAudio=(function tp_maybeTrashAudio(){var callIsActive=telephony&&(telephony.calls.length||telephony.conferenceGroup.calls.length);if(document.hidden&&!((this._channel==='telephony')&&callIsActive)){this._trashAudio();}}).bind(this);window.addEventListener('visibilitychange',this._maybeTrashAudio);telephony&&telephony.addEventListener('callschanged',this._maybeTrashAudio);this._initialized=true;},teardown:function tp_teardown(){var telephony=navigator.mozTelephony;telephony&&telephony.removeEventListener('callschanged',this._maybeTrashAudio);window.removeEventListener('visibilitychange',this._maybeTrashAudio);this._reset();this._initialized=false;},_reset:function tp_reset(){this._audioContext=null;this._channel=null;this._gainNode=null;this._playingNodes=[];this._maybeTrashAudio=null;},_ensureAudio:function tp_ensureAudio(){if(this._audioContext||!this._initialized){return;}
this._audioContext=new AudioContext();},_trashAudio:function tp_trashAudio(){this.stop();this._audioContext=null;},_startAt:function tp_startAt(frequencies,when,duration){var context=this._audioContext;var sampleRate=context.sampleRate;var envelope=context.createBuffer(1,(duration?duration:0.05)*sampleRate,sampleRate);for(var i=0;i<envelope.length;i++){var factor=kToneVolume;var t=i/sampleRate;if(t<=kAttackDuration){factor=t/kAttackDuration;}else if(t-kAttackDuration<=kDecayDuration){factor=1.0-(1.0-kToneVolume)*(t-kAttackDuration)/kDecayDuration;}
if(!duration){factor-=kToneVolume;}else if(t>duration-kReleaseDuration){factor*=(duration-t)/kReleaseDuration;}
envelope.getChannelData(0)[i]=factor*kMasterVolume;}
var gainNode=context.createGain();gainNode.connect(context.destination);if(!duration){this._gainNode=gainNode;}
var envelopeNode=context.createBufferSource();envelopeNode.buffer=envelope;envelopeNode.start(when);envelopeNode.connect(gainNode.gain);gainNode.gain.setValueAtTime(duration?0.0:kToneVolume*kMasterVolume,0.0);for(i=0;i<frequencies.length;++i){var oscNode=this._audioContext.createOscillator();oscNode.type='sine';oscNode.frequency.value=frequencies[i];oscNode.start(when);if(duration){oscNode.stop(Math.max(when,context.currentTime+0.5)+duration);}else{this._playingNodes.push(oscNode);}
oscNode.connect(gainNode);}},start:function tp_start(frequencies,shortPress){this._ensureAudio();this._startAt(frequencies,0,shortPress?kShortPressDuration:0);},stop:function tp_stop(){if(!this._gainNode){return;}
var context=this._audioContext;var sampleRate=context.sampleRate;var gain=this._gainNode.gain;this._gainNode=null;var ramp=context.createBuffer(1,kReleaseDuration*sampleRate,sampleRate);for(var i=0;i<ramp.length;i++){ramp.getChannelData(0)[i]=(ramp.length-i-1)/ramp.length*kToneVolume*kMasterVolume;}
var rampNode=context.createBufferSource();rampNode.buffer=ramp;rampNode.start();rampNode.connect(gain);gain.setValueAtTime(0.0,0.0);while(this._playingNodes.length){this._playingNodes.pop().stop(context.currentTime+kReleaseDuration+0.5);}},playSequence:function tp_playSequence(sequence){this._ensureAudio();var when=this._audioContext.currentTime+0.2;for(var index=0;index<sequence.length;++index){var step=sequence[index];var frequencies=step.slice(0,2);var duration=step[2]/1000;this._startAt(frequencies,when,duration);when+=duration;}}};

View file

@ -0,0 +1,9 @@
;'use strict';var Utils={prettyDate:function ut_prettyDate(time){var f=Intl.DateTimeFormat(navigator.languages,{hour12:navigator.mozHour12,hour:'numeric',minute:'numeric'});return f.format(new Date(time));},prettyDuration:function(node,duration,l10nPrefix){var elapsed=new Date(duration);var h=elapsed.getUTCHours();var m=elapsed.getUTCMinutes();var s=elapsed.getUTCSeconds();var l10nId=l10nPrefix||'callDuration';var durationL10n={h:h+'',m:m+'',s:s+''};if(l10nId==='callDuration'){durationL10n={h:(h>9?'':'0')+h,m:(m>9?'':'0')+m,s:(s>9?'':'0')+s};}
if(l10nPrefix==='callDurationTextFormat'&&h===0&&m===0){l10nId+='Seconds';}else{l10nId+=h>0?'Hours':'Minutes';}
navigator.mozL10n.setAttributes(node,l10nId,durationL10n);},setHeaderDate:function ut_setHeaderDate(elem,time){var diff=(Date.now()-time)/1000;var day_diff=Math.floor(diff/86400);var formattedTime;if(isNaN(day_diff)){elem.setAttribute('data-l10n-id','incorrectDate');return;}else if(day_diff===0){elem.setAttribute('data-l10n-id','today');return;}else if(day_diff===1){elem.setAttribute('data-l10n-id','yesterday');return;}else if(day_diff<6){formattedTime=(new Date(time)).toLocaleString(navigator.languages,{weekday:'long',});}else{formattedTime=(new Date(time)).toLocaleString(navigator.languages,{year:'2-digit',month:'2-digit',day:'2-digit'});}
elem.removeAttribute('data-l10n-id');elem.textContent=formattedTime;},getPhoneNumberPrimaryInfo:function ut_getPhoneNumberPrimaryInfo(matchingTel,contact){if(contact){if(contact.name&&contact.name.length&&contact.name[0]!==''){return contact.name;}else if(contact.org&&contact.org.length&&contact.org[0]!==''){return contact.org;}}
if(matchingTel){return matchingTel.value;}
return null;},toCamelCase:function ut_toCamelCase(str){return str.replace(/\-(.)/g,function replacer(str,p1){return p1.toUpperCase();});},_phoneTypesL10n:{'mobile':'phone_type_mobile','home':'phone_type_home','work':'phone_type_work','personal':'phone_type_personal','faxHome':'phone_type_fax_home','faxOffice':'phone_type_fax_office','faxOther':'phone_type_fax_other','other':'phone_type_other'},getPhoneNumberAdditionalInfo:function ut_getPhoneNumberAdditionalInfo(matchingTel){var type=matchingTel.type||'mobile';var carrier=matchingTel.carrier;if(Array.isArray(type)){type=type[0];}
var id;var args={};if(this._phoneTypesL10n.hasOwnProperty(type)){id=this._phoneTypesL10n[type];}else{id='phone_type_custom';args.type=type;}
if(carrier){id+='_and_carrier';args.carrier=carrier;}
return{id:id,args:Object.keys(args).length?args:null};},isPhoneType:function ut_isPhoneType(type){return this._phoneTypesL10n.hasOwnProperty(type);}};