Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions plugin.xml
Original file line numberDiff line numberDiff line change
Expand Up@@ -32,5 +32,15 @@
<source-file src="src/ios/VolumeSlider.m" />
<framework src="MediaPlayer.framework" weak="true" />
</platform>

<!-- android -->
<platform name="android">
<config-file target="res/xml/config.xml" parent="/*">
<feature name="VolumeSlider">
<param name="android-package" value="org.devgeeks.volumeslider.VolumeSlider" />
</feature>
</config-file>

<source-file src="src/android/VolumeSlider.java" target-dir="src/org/devgeeks/volumeslider" />
</platform>
</plugin>
149 changes: 149 additions & 0 deletions src/android/VolumeSlider.java
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
package org.devgeeks.volumeslider;

import android.content.Context;
import android.media.AudioManager;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.SeekBar;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaArgs;
import org.apache.cordova.CordovaPlugin;
import org.json.JSONException;
import android.util.Log;

public class VolumeSlider extends CordovaPlugin {
private SeekBar volumeSeekBar;
private AudioManager audioManager;
private static final String TAG = "volume_slider";
double current_volume = 0.2;

private int cssToViewUnit(double size) {
return (int)Math.abs(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, (float)size,
cordova.getActivity().getResources().getDisplayMetrics()));
}

private double cssToViewUnitDouble(double size) {
return TypedValue.applyDimension(TypedValue.TYPE_NULL, (float)size,
cordova.getActivity().getResources().getDisplayMetrics());
}

@Override
public boolean execute(String action, CordovaArgs args, CallbackContext callbackContext) throws JSONException {
if (action == null)
return false;
if (action.equals("createVolumeSlider")) {
final int x = cssToViewUnit(args.getDouble(0));
final int y = cssToViewUnit(args.getDouble(1));
final int width = cssToViewUnit(args.getDouble(2));
final int height = cssToViewUnit(args.getDouble(3));
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
createVolumeSlider(x, y, width, height);
}
});
return true;
}
if (action.equals("showVolumeSlider")) {
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
showVolumeSlider();
}
});
return true;
}
if (action.equals("hideVolumeSlider")) {
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
hideVolumeSlider();
}
});
return true;
}
if (action.equals("setVolumeSlider")) {
final double volume = cssToViewUnitDouble(args.getDouble(0));
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
setVolumeSlider(volume);
}
});
return true;
}
if (action.equals("resetVolumeSlider")) {
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
resetVolumeSlider();
}
});
return true;
}
return false;
}

private void bindVolumeSeekBarToAudioManager(SeekBar volumeSeekBar, final Context context)
{
audioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
volumeSeekBar.setMax(audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC));
volumeSeekBar.setProgress(audioManager.getStreamVolume(AudioManager.STREAM_MUSIC));

volumeSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, progress, 0);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {}
});
}

private void createVolumeSlider(int x, int y, int width, int height) {
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(width, height);
params.leftMargin = x;
params.topMargin = y;

Context context = cordova.getActivity();

volumeSeekBar = new SeekBar(context);
bindVolumeSeekBarToAudioManager(volumeSeekBar, context);

// Record current media volume to revert to with resetVolumeSlider()
current_volume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
Log.d(TAG, "CURRENT VOLUME = " + current_volume);
hideVolumeSlider();

RelativeLayout layout = new RelativeLayout(context);
layout.addView(volumeSeekBar, params);
ViewGroup container = (ViewGroup)cordova.getActivity().findViewById(android.R.id.content);
container.addView(layout);
}

private void showVolumeSlider() {
volumeSeekBar.setVisibility(View.VISIBLE);
}

private void hideVolumeSlider() {
volumeSeekBar.setVisibility(View.INVISIBLE);
}

private void setVolumeSlider(double volume) {
// We map volume to a range of 0.0 - 1.0
Log.d(TAG, "SET VOLUME TO: " + volume);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, (int)(volume * audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)), 0);
}

private void resetVolumeSlider() {
// Resetting back to initial volume
Log.d(TAG, "RESET VOLUME TO: " + current_volume);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, (int)(current_volume), 0);
}
}
2 changes: 2 additions & 0 deletions src/ios/VolumeSlider.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -25,5 +25,7 @@
- (void)createVolumeSlider:(CDVInvokedUrlCommand *)command;
- (void)showVolumeSlider:(CDVInvokedUrlCommand *)command;
- (void)hideVolumeSlider:(CDVInvokedUrlCommand *)command;
- (void)setVolumeSlider:(CDVInvokedUrlCommand *)command;
- (void)resetVolumeSlider:(CDVInvokedUrlCommand *)command;

@end
45 changes: 43 additions & 2 deletions src/ios/VolumeSlider.m
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,6 +14,9 @@ @implementation VolumeSlider

@synthesize mpVolumeViewParentView, myVolumeView, callbackId;

float userVolume = 0.2;
UISlider* volumeViewSlider = nil;

#ifndef __IPHONE_3_0
@synthesize webView;
#endif
Expand All@@ -30,7 +33,8 @@ -(CDVPlugin*) initWithWebView:(UIWebView*)theWebView

- (void) createVolumeSlider:(CDVInvokedUrlCommand *)command
{
NSArray* arguments = [command arguments];
NSLog(@"In createVolumeSlider");
NSArray* arguments = [command arguments];

self.callbackId = command.callbackId;
NSUInteger argc = [arguments count];
Expand All@@ -40,7 +44,7 @@ - (void) createVolumeSlider:(CDVInvokedUrlCommand *)command
}

if (self.mpVolumeViewParentView != NULL) {
return;//already created, don't need to create it again
// return;//already created, don't need to create it again
}

CGFloat originx,originy,width;
Expand DownExpand Up@@ -68,12 +72,25 @@ - (void) createVolumeSlider:(CDVInvokedUrlCommand *)command
[[MPVolumeView alloc] initWithFrame: mpVolumeViewParentView.bounds];
[mpVolumeViewParentView addSubview: myVolumeView];
self.myVolumeView.showsVolumeSlider = NO;


volumeViewSlider = nil;
for (UIView *view in [self.myVolumeView subviews]){
if ([view.class.description isEqualToString:@"MPVolumeSlider"]){
volumeViewSlider = (UISlider*)view;
NSLog(@"Found MPVolumeslider : %f" ,userVolume );
break;
}
}
userVolume = volumeViewSlider.value;

}

- (void)showVolumeSlider:(CDVInvokedUrlCommand *)command
{
self.myVolumeView.showsVolumeSlider = YES;
self.mpVolumeViewParentView.hidden = NO;

}

- (void)hideVolumeSlider:(CDVInvokedUrlCommand *)command
Expand All@@ -82,6 +99,30 @@ - (void)hideVolumeSlider:(CDVInvokedUrlCommand *)command
self.myVolumeView.showsVolumeSlider = NO;
}

- (void)setVolumeSlider:(CDVInvokedUrlCommand *)command
{
self.mpVolumeViewParentView.hidden = YES;
self.myVolumeView.showsVolumeSlider = NO;

NSArray* arguments = [command arguments];
NSUInteger argc = [arguments count];

if (argc < 1) { // at a minimum we need the value to be set...
return;
}
float setVolume = [[arguments objectAtIndex:0] floatValue];

[volumeViewSlider setValue:setVolume animated:NO];
[volumeViewSlider sendActionsForControlEvents:UIControlEventTouchUpInside];

}

- (void)resetVolumeSlider:(CDVInvokedUrlCommand *)command
{
[volumeViewSlider setValue:userVolume animated:NO];
[volumeViewSlider sendActionsForControlEvents:UIControlEventTouchUpInside];

}


@end
18 changes: 16 additions & 2 deletions www/VolumeSlider.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@ var exec = require('cordova/exec');
module.exports = {

/**
* Create a volume slider.
* Create a volume slider, and save the user's current set volume.
*/
createVolumeSlider : function(originx,originy,width,height) {
exec(null, null, "VolumeSlider","createVolumeSlider", [originx, originy, width, height]);
Expand All@@ -31,5 +31,19 @@ module.exports = {
*/
hideVolumeSlider : function() {
exec(null, null, "VolumeSlider","hideVolumeSlider", []);
}
},

/**
* Set the device's master volume
*/
setVolumeSlider : function(set_volume) {
exec(null, null, "VolumeSlider","setVolumeSlider", [set_volume]);
},

/**
* Reset the volume slider to the original user volume present uon creation of this slider
*/
resetVolumeSlider : function() {
exec(null, null, "VolumeSlider","resetVolumeSlider", []);
}
};
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions plugin.xml
Original file line numberDiff line numberDiff line change
Expand Up@@ -32,5 +32,15 @@
<source-file src="src/ios/VolumeSlider.m" />
<framework src="MediaPlayer.framework" weak="true" />
</platform>

<!-- android -->
<platform name="android">
<config-file target="res/xml/config.xml" parent="/*">
<feature name="VolumeSlider">
<param name="android-package" value="org.devgeeks.volumeslider.VolumeSlider" />
</feature>
</config-file>

<source-file src="src/android/VolumeSlider.java" target-dir="src/org/devgeeks/volumeslider" />
</platform>
</plugin>
149 changes: 149 additions & 0 deletions src/android/VolumeSlider.java
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
package org.devgeeks.volumeslider;

import android.content.Context;
import android.media.AudioManager;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.SeekBar;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaArgs;
import org.apache.cordova.CordovaPlugin;
import org.json.JSONException;
import android.util.Log;

public class VolumeSlider extends CordovaPlugin {
private SeekBar volumeSeekBar;
private AudioManager audioManager;
private static final String TAG = "volume_slider";
double current_volume = 0.2;

private int cssToViewUnit(double size) {
return (int)Math.abs(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, (float)size,
cordova.getActivity().getResources().getDisplayMetrics()));
}

private double cssToViewUnitDouble(double size) {
return TypedValue.applyDimension(TypedValue.TYPE_NULL, (float)size,
cordova.getActivity().getResources().getDisplayMetrics());
}

@Override
public boolean execute(String action, CordovaArgs args, CallbackContext callbackContext) throws JSONException {
if (action == null)
return false;
if (action.equals("createVolumeSlider")) {
final int x = cssToViewUnit(args.getDouble(0));
final int y = cssToViewUnit(args.getDouble(1));
final int width = cssToViewUnit(args.getDouble(2));
final int height = cssToViewUnit(args.getDouble(3));
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
createVolumeSlider(x, y, width, height);
}
});
return true;
}
if (action.equals("showVolumeSlider")) {
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
showVolumeSlider();
}
});
return true;
}
if (action.equals("hideVolumeSlider")) {
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
hideVolumeSlider();
}
});
return true;
}
if (action.equals("setVolumeSlider")) {
final double volume = cssToViewUnitDouble(args.getDouble(0));
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
setVolumeSlider(volume);
}
});
return true;
}
if (action.equals("resetVolumeSlider")) {
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
resetVolumeSlider();
}
});
return true;
}
return false;
}

private void bindVolumeSeekBarToAudioManager(SeekBar volumeSeekBar, final Context context)
{
audioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
volumeSeekBar.setMax(audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC));
volumeSeekBar.setProgress(audioManager.getStreamVolume(AudioManager.STREAM_MUSIC));

volumeSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, progress, 0);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {}
});
}

private void createVolumeSlider(int x, int y, int width, int height) {
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(width, height);
params.leftMargin = x;
params.topMargin = y;

Context context = cordova.getActivity();

volumeSeekBar = new SeekBar(context);
bindVolumeSeekBarToAudioManager(volumeSeekBar, context);

// Record current media volume to revert to with resetVolumeSlider()
current_volume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
Log.d(TAG, "CURRENT VOLUME = " + current_volume);
hideVolumeSlider();

RelativeLayout layout = new RelativeLayout(context);
layout.addView(volumeSeekBar, params);
ViewGroup container = (ViewGroup)cordova.getActivity().findViewById(android.R.id.content);
container.addView(layout);
}

private void showVolumeSlider() {
volumeSeekBar.setVisibility(View.VISIBLE);
}

private void hideVolumeSlider() {
volumeSeekBar.setVisibility(View.INVISIBLE);
}

private void setVolumeSlider(double volume) {
// We map volume to a range of 0.0 - 1.0
Log.d(TAG, "SET VOLUME TO: " + volume);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, (int)(volume * audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)), 0);
}

private void resetVolumeSlider() {
// Resetting back to initial volume
Log.d(TAG, "RESET VOLUME TO: " + current_volume);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, (int)(current_volume), 0);
}
}
2 changes: 2 additions & 0 deletions src/ios/VolumeSlider.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -25,5 +25,7 @@
- (void)createVolumeSlider:(CDVInvokedUrlCommand *)command;
- (void)showVolumeSlider:(CDVInvokedUrlCommand *)command;
- (void)hideVolumeSlider:(CDVInvokedUrlCommand *)command;
- (void)setVolumeSlider:(CDVInvokedUrlCommand *)command;
- (void)resetVolumeSlider:(CDVInvokedUrlCommand *)command;

@end
45 changes: 43 additions & 2 deletions src/ios/VolumeSlider.m
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,6 +14,9 @@ @implementation VolumeSlider

@synthesize mpVolumeViewParentView, myVolumeView, callbackId;

float userVolume = 0.2;
UISlider* volumeViewSlider = nil;

#ifndef __IPHONE_3_0
@synthesize webView;
#endif
Expand All@@ -30,7 +33,8 @@ -(CDVPlugin*) initWithWebView:(UIWebView*)theWebView

- (void) createVolumeSlider:(CDVInvokedUrlCommand *)command
{
NSArray* arguments = [command arguments];
NSLog(@"In createVolumeSlider");
NSArray* arguments = [command arguments];

self.callbackId = command.callbackId;
NSUInteger argc = [arguments count];
Expand All@@ -40,7 +44,7 @@ - (void) createVolumeSlider:(CDVInvokedUrlCommand *)command
}

if (self.mpVolumeViewParentView != NULL) {
return;//already created, don't need to create it again
// return;//already created, don't need to create it again
}

CGFloat originx,originy,width;
Expand DownExpand Up@@ -68,12 +72,25 @@ - (void) createVolumeSlider:(CDVInvokedUrlCommand *)command
[[MPVolumeView alloc] initWithFrame: mpVolumeViewParentView.bounds];
[mpVolumeViewParentView addSubview: myVolumeView];
self.myVolumeView.showsVolumeSlider = NO;


volumeViewSlider = nil;
for (UIView *view in [self.myVolumeView subviews]){
if ([view.class.description isEqualToString:@"MPVolumeSlider"]){
volumeViewSlider = (UISlider*)view;
NSLog(@"Found MPVolumeslider : %f" ,userVolume );
break;
}
}
userVolume = volumeViewSlider.value;

}

- (void)showVolumeSlider:(CDVInvokedUrlCommand *)command
{
self.myVolumeView.showsVolumeSlider = YES;
self.mpVolumeViewParentView.hidden = NO;

}

- (void)hideVolumeSlider:(CDVInvokedUrlCommand *)command
Expand All@@ -82,6 +99,30 @@ - (void)hideVolumeSlider:(CDVInvokedUrlCommand *)command
self.myVolumeView.showsVolumeSlider = NO;
}

- (void)setVolumeSlider:(CDVInvokedUrlCommand *)command
{
self.mpVolumeViewParentView.hidden = YES;
self.myVolumeView.showsVolumeSlider = NO;

NSArray* arguments = [command arguments];
NSUInteger argc = [arguments count];

if (argc < 1) { // at a minimum we need the value to be set...
return;
}
float setVolume = [[arguments objectAtIndex:0] floatValue];

[volumeViewSlider setValue:setVolume animated:NO];
[volumeViewSlider sendActionsForControlEvents:UIControlEventTouchUpInside];

}

- (void)resetVolumeSlider:(CDVInvokedUrlCommand *)command
{
[volumeViewSlider setValue:userVolume animated:NO];
[volumeViewSlider sendActionsForControlEvents:UIControlEventTouchUpInside];

}


@end
18 changes: 16 additions & 2 deletions www/VolumeSlider.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@ var exec = require('cordova/exec');
module.exports = {

/**
* Create a volume slider.
* Create a volume slider, and save the user's current set volume.
*/
createVolumeSlider : function(originx,originy,width,height) {
exec(null, null, "VolumeSlider","createVolumeSlider", [originx, originy, width, height]);
Expand All@@ -31,5 +31,19 @@ module.exports = {
*/
hideVolumeSlider : function() {
exec(null, null, "VolumeSlider","hideVolumeSlider", []);
}
},

/**
* Set the device's master volume
*/
setVolumeSlider : function(set_volume) {
exec(null, null, "VolumeSlider","setVolumeSlider", [set_volume]);
},

/**
* Reset the volume slider to the original user volume present uon creation of this slider
*/
resetVolumeSlider : function() {
exec(null, null, "VolumeSlider","resetVolumeSlider", []);
}
};
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions plugin.xml
Original file line numberDiff line numberDiff line change
Expand Up@@ -32,5 +32,15 @@
<source-file src="src/ios/VolumeSlider.m" />
<framework src="MediaPlayer.framework" weak="true" />
</platform>

<!-- android -->
<platform name="android">
<config-file target="res/xml/config.xml" parent="/*">
<feature name="VolumeSlider">
<param name="android-package" value="org.devgeeks.volumeslider.VolumeSlider" />
</feature>
</config-file>

<source-file src="src/android/VolumeSlider.java" target-dir="src/org/devgeeks/volumeslider" />
</platform>
</plugin>
149 changes: 149 additions & 0 deletions src/android/VolumeSlider.java
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
package org.devgeeks.volumeslider;

import android.content.Context;
import android.media.AudioManager;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.SeekBar;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaArgs;
import org.apache.cordova.CordovaPlugin;
import org.json.JSONException;
import android.util.Log;

public class VolumeSlider extends CordovaPlugin {
private SeekBar volumeSeekBar;
private AudioManager audioManager;
private static final String TAG = "volume_slider";
double current_volume = 0.2;

private int cssToViewUnit(double size) {
return (int)Math.abs(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, (float)size,
cordova.getActivity().getResources().getDisplayMetrics()));
}

private double cssToViewUnitDouble(double size) {
return TypedValue.applyDimension(TypedValue.TYPE_NULL, (float)size,
cordova.getActivity().getResources().getDisplayMetrics());
}

@Override
public boolean execute(String action, CordovaArgs args, CallbackContext callbackContext) throws JSONException {
if (action == null)
return false;
if (action.equals("createVolumeSlider")) {
final int x = cssToViewUnit(args.getDouble(0));
final int y = cssToViewUnit(args.getDouble(1));
final int width = cssToViewUnit(args.getDouble(2));
final int height = cssToViewUnit(args.getDouble(3));
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
createVolumeSlider(x, y, width, height);
}
});
return true;
}
if (action.equals("showVolumeSlider")) {
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
showVolumeSlider();
}
});
return true;
}
if (action.equals("hideVolumeSlider")) {
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
hideVolumeSlider();
}
});
return true;
}
if (action.equals("setVolumeSlider")) {
final double volume = cssToViewUnitDouble(args.getDouble(0));
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
setVolumeSlider(volume);
}
});
return true;
}
if (action.equals("resetVolumeSlider")) {
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
resetVolumeSlider();
}
});
return true;
}
return false;
}

private void bindVolumeSeekBarToAudioManager(SeekBar volumeSeekBar, final Context context)
{
audioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
volumeSeekBar.setMax(audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC));
volumeSeekBar.setProgress(audioManager.getStreamVolume(AudioManager.STREAM_MUSIC));

volumeSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, progress, 0);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {}
});
}

private void createVolumeSlider(int x, int y, int width, int height) {
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(width, height);
params.leftMargin = x;
params.topMargin = y;

Context context = cordova.getActivity();

volumeSeekBar = new SeekBar(context);
bindVolumeSeekBarToAudioManager(volumeSeekBar, context);

// Record current media volume to revert to with resetVolumeSlider()
current_volume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
Log.d(TAG, "CURRENT VOLUME = " + current_volume);
hideVolumeSlider();

RelativeLayout layout = new RelativeLayout(context);
layout.addView(volumeSeekBar, params);
ViewGroup container = (ViewGroup)cordova.getActivity().findViewById(android.R.id.content);
container.addView(layout);
}

private void showVolumeSlider() {
volumeSeekBar.setVisibility(View.VISIBLE);
}

private void hideVolumeSlider() {
volumeSeekBar.setVisibility(View.INVISIBLE);
}

private void setVolumeSlider(double volume) {
// We map volume to a range of 0.0 - 1.0
Log.d(TAG, "SET VOLUME TO: " + volume);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, (int)(volume * audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)), 0);
}

private void resetVolumeSlider() {
// Resetting back to initial volume
Log.d(TAG, "RESET VOLUME TO: " + current_volume);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, (int)(current_volume), 0);
}
}
2 changes: 2 additions & 0 deletions src/ios/VolumeSlider.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -25,5 +25,7 @@
- (void)createVolumeSlider:(CDVInvokedUrlCommand *)command;
- (void)showVolumeSlider:(CDVInvokedUrlCommand *)command;
- (void)hideVolumeSlider:(CDVInvokedUrlCommand *)command;
- (void)setVolumeSlider:(CDVInvokedUrlCommand *)command;
- (void)resetVolumeSlider:(CDVInvokedUrlCommand *)command;

@end
45 changes: 43 additions & 2 deletions src/ios/VolumeSlider.m
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,6 +14,9 @@ @implementation VolumeSlider

@synthesize mpVolumeViewParentView, myVolumeView, callbackId;

float userVolume = 0.2;
UISlider* volumeViewSlider = nil;

#ifndef __IPHONE_3_0
@synthesize webView;
#endif
Expand All@@ -30,7 +33,8 @@ -(CDVPlugin*) initWithWebView:(UIWebView*)theWebView

- (void) createVolumeSlider:(CDVInvokedUrlCommand *)command
{
NSArray* arguments = [command arguments];
NSLog(@"In createVolumeSlider");
NSArray* arguments = [command arguments];

self.callbackId = command.callbackId;
NSUInteger argc = [arguments count];
Expand All@@ -40,7 +44,7 @@ - (void) createVolumeSlider:(CDVInvokedUrlCommand *)command
}

if (self.mpVolumeViewParentView != NULL) {
return;//already created, don't need to create it again
// return;//already created, don't need to create it again
}

CGFloat originx,originy,width;
Expand DownExpand Up@@ -68,12 +72,25 @@ - (void) createVolumeSlider:(CDVInvokedUrlCommand *)command
[[MPVolumeView alloc] initWithFrame: mpVolumeViewParentView.bounds];
[mpVolumeViewParentView addSubview: myVolumeView];
self.myVolumeView.showsVolumeSlider = NO;


volumeViewSlider = nil;
for (UIView *view in [self.myVolumeView subviews]){
if ([view.class.description isEqualToString:@"MPVolumeSlider"]){
volumeViewSlider = (UISlider*)view;
NSLog(@"Found MPVolumeslider : %f" ,userVolume );
break;
}
}
userVolume = volumeViewSlider.value;

}

- (void)showVolumeSlider:(CDVInvokedUrlCommand *)command
{
self.myVolumeView.showsVolumeSlider = YES;
self.mpVolumeViewParentView.hidden = NO;

}

- (void)hideVolumeSlider:(CDVInvokedUrlCommand *)command
Expand All@@ -82,6 +99,30 @@ - (void)hideVolumeSlider:(CDVInvokedUrlCommand *)command
self.myVolumeView.showsVolumeSlider = NO;
}

- (void)setVolumeSlider:(CDVInvokedUrlCommand *)command
{
self.mpVolumeViewParentView.hidden = YES;
self.myVolumeView.showsVolumeSlider = NO;

NSArray* arguments = [command arguments];
NSUInteger argc = [arguments count];

if (argc < 1) { // at a minimum we need the value to be set...
return;
}
float setVolume = [[arguments objectAtIndex:0] floatValue];

[volumeViewSlider setValue:setVolume animated:NO];
[volumeViewSlider sendActionsForControlEvents:UIControlEventTouchUpInside];

}

- (void)resetVolumeSlider:(CDVInvokedUrlCommand *)command
{
[volumeViewSlider setValue:userVolume animated:NO];
[volumeViewSlider sendActionsForControlEvents:UIControlEventTouchUpInside];

}


@end
18 changes: 16 additions & 2 deletions www/VolumeSlider.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@ var exec = require('cordova/exec');
module.exports = {

/**
* Create a volume slider.
* Create a volume slider, and save the user's current set volume.
*/
createVolumeSlider : function(originx,originy,width,height) {
exec(null, null, "VolumeSlider","createVolumeSlider", [originx, originy, width, height]);
Expand All@@ -31,5 +31,19 @@ module.exports = {
*/
hideVolumeSlider : function() {
exec(null, null, "VolumeSlider","hideVolumeSlider", []);
}
},

/**
* Set the device's master volume
*/
setVolumeSlider : function(set_volume) {
exec(null, null, "VolumeSlider","setVolumeSlider", [set_volume]);
},

/**
* Reset the volume slider to the original user volume present uon creation of this slider
*/
resetVolumeSlider : function() {
exec(null, null, "VolumeSlider","resetVolumeSlider", []);
}
};
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions plugin.xml
Original file line numberDiff line numberDiff line change
Expand Up@@ -32,5 +32,15 @@
<source-file src="src/ios/VolumeSlider.m" />
<framework src="MediaPlayer.framework" weak="true" />
</platform>

<!-- android -->
<platform name="android">
<config-file target="res/xml/config.xml" parent="/*">
<feature name="VolumeSlider">
<param name="android-package" value="org.devgeeks.volumeslider.VolumeSlider" />
</feature>
</config-file>

<source-file src="src/android/VolumeSlider.java" target-dir="src/org/devgeeks/volumeslider" />
</platform>
</plugin>
149 changes: 149 additions & 0 deletions src/android/VolumeSlider.java
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
package org.devgeeks.volumeslider;

import android.content.Context;
import android.media.AudioManager;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.SeekBar;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaArgs;
import org.apache.cordova.CordovaPlugin;
import org.json.JSONException;
import android.util.Log;

public class VolumeSlider extends CordovaPlugin {
private SeekBar volumeSeekBar;
private AudioManager audioManager;
private static final String TAG = "volume_slider";
double current_volume = 0.2;

private int cssToViewUnit(double size) {
return (int)Math.abs(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, (float)size,
cordova.getActivity().getResources().getDisplayMetrics()));
}

private double cssToViewUnitDouble(double size) {
return TypedValue.applyDimension(TypedValue.TYPE_NULL, (float)size,
cordova.getActivity().getResources().getDisplayMetrics());
}

@Override
public boolean execute(String action, CordovaArgs args, CallbackContext callbackContext) throws JSONException {
if (action == null)
return false;
if (action.equals("createVolumeSlider")) {
final int x = cssToViewUnit(args.getDouble(0));
final int y = cssToViewUnit(args.getDouble(1));
final int width = cssToViewUnit(args.getDouble(2));
final int height = cssToViewUnit(args.getDouble(3));
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
createVolumeSlider(x, y, width, height);
}
});
return true;
}
if (action.equals("showVolumeSlider")) {
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
showVolumeSlider();
}
});
return true;
}
if (action.equals("hideVolumeSlider")) {
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
hideVolumeSlider();
}
});
return true;
}
if (action.equals("setVolumeSlider")) {
final double volume = cssToViewUnitDouble(args.getDouble(0));
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
setVolumeSlider(volume);
}
});
return true;
}
if (action.equals("resetVolumeSlider")) {
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
resetVolumeSlider();
}
});
return true;
}
return false;
}

private void bindVolumeSeekBarToAudioManager(SeekBar volumeSeekBar, final Context context)
{
audioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
volumeSeekBar.setMax(audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC));
volumeSeekBar.setProgress(audioManager.getStreamVolume(AudioManager.STREAM_MUSIC));

volumeSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, progress, 0);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {}
});
}

private void createVolumeSlider(int x, int y, int width, int height) {
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(width, height);
params.leftMargin = x;
params.topMargin = y;

Context context = cordova.getActivity();

volumeSeekBar = new SeekBar(context);
bindVolumeSeekBarToAudioManager(volumeSeekBar, context);

// Record current media volume to revert to with resetVolumeSlider()
current_volume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
Log.d(TAG, "CURRENT VOLUME = " + current_volume);
hideVolumeSlider();

RelativeLayout layout = new RelativeLayout(context);
layout.addView(volumeSeekBar, params);
ViewGroup container = (ViewGroup)cordova.getActivity().findViewById(android.R.id.content);
container.addView(layout);
}

private void showVolumeSlider() {
volumeSeekBar.setVisibility(View.VISIBLE);
}

private void hideVolumeSlider() {
volumeSeekBar.setVisibility(View.INVISIBLE);
}

private void setVolumeSlider(double volume) {
// We map volume to a range of 0.0 - 1.0
Log.d(TAG, "SET VOLUME TO: " + volume);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, (int)(volume * audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)), 0);
}

private void resetVolumeSlider() {
// Resetting back to initial volume
Log.d(TAG, "RESET VOLUME TO: " + current_volume);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, (int)(current_volume), 0);
}
}
2 changes: 2 additions & 0 deletions src/ios/VolumeSlider.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -25,5 +25,7 @@
- (void)createVolumeSlider:(CDVInvokedUrlCommand *)command;
- (void)showVolumeSlider:(CDVInvokedUrlCommand *)command;
- (void)hideVolumeSlider:(CDVInvokedUrlCommand *)command;
- (void)setVolumeSlider:(CDVInvokedUrlCommand *)command;
- (void)resetVolumeSlider:(CDVInvokedUrlCommand *)command;

@end
45 changes: 43 additions & 2 deletions src/ios/VolumeSlider.m
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,6 +14,9 @@ @implementation VolumeSlider

@synthesize mpVolumeViewParentView, myVolumeView, callbackId;

float userVolume = 0.2;
UISlider* volumeViewSlider = nil;

#ifndef __IPHONE_3_0
@synthesize webView;
#endif
Expand All@@ -30,7 +33,8 @@ -(CDVPlugin*) initWithWebView:(UIWebView*)theWebView

- (void) createVolumeSlider:(CDVInvokedUrlCommand *)command
{
NSArray* arguments = [command arguments];
NSLog(@"In createVolumeSlider");
NSArray* arguments = [command arguments];

self.callbackId = command.callbackId;
NSUInteger argc = [arguments count];
Expand All@@ -40,7 +44,7 @@ - (void) createVolumeSlider:(CDVInvokedUrlCommand *)command
}

if (self.mpVolumeViewParentView != NULL) {
return;//already created, don't need to create it again
// return;//already created, don't need to create it again
}

CGFloat originx,originy,width;
Expand DownExpand Up@@ -68,12 +72,25 @@ - (void) createVolumeSlider:(CDVInvokedUrlCommand *)command
[[MPVolumeView alloc] initWithFrame: mpVolumeViewParentView.bounds];
[mpVolumeViewParentView addSubview: myVolumeView];
self.myVolumeView.showsVolumeSlider = NO;


volumeViewSlider = nil;
for (UIView *view in [self.myVolumeView subviews]){
if ([view.class.description isEqualToString:@"MPVolumeSlider"]){
volumeViewSlider = (UISlider*)view;
NSLog(@"Found MPVolumeslider : %f" ,userVolume );
break;
}
}
userVolume = volumeViewSlider.value;

}

- (void)showVolumeSlider:(CDVInvokedUrlCommand *)command
{
self.myVolumeView.showsVolumeSlider = YES;
self.mpVolumeViewParentView.hidden = NO;

}

- (void)hideVolumeSlider:(CDVInvokedUrlCommand *)command
Expand All@@ -82,6 +99,30 @@ - (void)hideVolumeSlider:(CDVInvokedUrlCommand *)command
self.myVolumeView.showsVolumeSlider = NO;
}

- (void)setVolumeSlider:(CDVInvokedUrlCommand *)command
{
self.mpVolumeViewParentView.hidden = YES;
self.myVolumeView.showsVolumeSlider = NO;

NSArray* arguments = [command arguments];
NSUInteger argc = [arguments count];

if (argc < 1) { // at a minimum we need the value to be set...
return;
}
float setVolume = [[arguments objectAtIndex:0] floatValue];

[volumeViewSlider setValue:setVolume animated:NO];
[volumeViewSlider sendActionsForControlEvents:UIControlEventTouchUpInside];

}

- (void)resetVolumeSlider:(CDVInvokedUrlCommand *)command
{
[volumeViewSlider setValue:userVolume animated:NO];
[volumeViewSlider sendActionsForControlEvents:UIControlEventTouchUpInside];

}


@end
18 changes: 16 additions & 2 deletions www/VolumeSlider.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@ var exec = require('cordova/exec');
module.exports = {

/**
* Create a volume slider.
* Create a volume slider, and save the user's current set volume.
*/
createVolumeSlider : function(originx,originy,width,height) {
exec(null, null, "VolumeSlider","createVolumeSlider", [originx, originy, width, height]);
Expand All@@ -31,5 +31,19 @@ module.exports = {
*/
hideVolumeSlider : function() {
exec(null, null, "VolumeSlider","hideVolumeSlider", []);
}
},

/**
* Set the device's master volume
*/
setVolumeSlider : function(set_volume) {
exec(null, null, "VolumeSlider","setVolumeSlider", [set_volume]);
},

/**
* Reset the volume slider to the original user volume present uon creation of this slider
*/
resetVolumeSlider : function() {
exec(null, null, "VolumeSlider","resetVolumeSlider", []);
}
};
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions plugin.xml
Original file line numberDiff line numberDiff line change
Expand Up@@ -32,5 +32,15 @@
<source-file src="src/ios/VolumeSlider.m" />
<framework src="MediaPlayer.framework" weak="true" />
</platform>

<!-- android -->
<platform name="android">
<config-file target="res/xml/config.xml" parent="/*">
<feature name="VolumeSlider">
<param name="android-package" value="org.devgeeks.volumeslider.VolumeSlider" />
</feature>
</config-file>

<source-file src="src/android/VolumeSlider.java" target-dir="src/org/devgeeks/volumeslider" />
</platform>
</plugin>
149 changes: 149 additions & 0 deletions src/android/VolumeSlider.java
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
package org.devgeeks.volumeslider;

import android.content.Context;
import android.media.AudioManager;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.SeekBar;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaArgs;
import org.apache.cordova.CordovaPlugin;
import org.json.JSONException;
import android.util.Log;

public class VolumeSlider extends CordovaPlugin {
private SeekBar volumeSeekBar;
private AudioManager audioManager;
private static final String TAG = "volume_slider";
double current_volume = 0.2;

private int cssToViewUnit(double size) {
return (int)Math.abs(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, (float)size,
cordova.getActivity().getResources().getDisplayMetrics()));
}

private double cssToViewUnitDouble(double size) {
return TypedValue.applyDimension(TypedValue.TYPE_NULL, (float)size,
cordova.getActivity().getResources().getDisplayMetrics());
}

@Override
public boolean execute(String action, CordovaArgs args, CallbackContext callbackContext) throws JSONException {
if (action == null)
return false;
if (action.equals("createVolumeSlider")) {
final int x = cssToViewUnit(args.getDouble(0));
final int y = cssToViewUnit(args.getDouble(1));
final int width = cssToViewUnit(args.getDouble(2));
final int height = cssToViewUnit(args.getDouble(3));
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
createVolumeSlider(x, y, width, height);
}
});
return true;
}
if (action.equals("showVolumeSlider")) {
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
showVolumeSlider();
}
});
return true;
}
if (action.equals("hideVolumeSlider")) {
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
hideVolumeSlider();
}
});
return true;
}
if (action.equals("setVolumeSlider")) {
final double volume = cssToViewUnitDouble(args.getDouble(0));
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
setVolumeSlider(volume);
}
});
return true;
}
if (action.equals("resetVolumeSlider")) {
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
resetVolumeSlider();
}
});
return true;
}
return false;
}

private void bindVolumeSeekBarToAudioManager(SeekBar volumeSeekBar, final Context context)
{
audioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
volumeSeekBar.setMax(audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC));
volumeSeekBar.setProgress(audioManager.getStreamVolume(AudioManager.STREAM_MUSIC));

volumeSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, progress, 0);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {}
});
}

private void createVolumeSlider(int x, int y, int width, int height) {
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(width, height);
params.leftMargin = x;
params.topMargin = y;

Context context = cordova.getActivity();

volumeSeekBar = new SeekBar(context);
bindVolumeSeekBarToAudioManager(volumeSeekBar, context);

// Record current media volume to revert to with resetVolumeSlider()
current_volume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
Log.d(TAG, "CURRENT VOLUME = " + current_volume);
hideVolumeSlider();

RelativeLayout layout = new RelativeLayout(context);
layout.addView(volumeSeekBar, params);
ViewGroup container = (ViewGroup)cordova.getActivity().findViewById(android.R.id.content);
container.addView(layout);
}

private void showVolumeSlider() {
volumeSeekBar.setVisibility(View.VISIBLE);
}

private void hideVolumeSlider() {
volumeSeekBar.setVisibility(View.INVISIBLE);
}

private void setVolumeSlider(double volume) {
// We map volume to a range of 0.0 - 1.0
Log.d(TAG, "SET VOLUME TO: " + volume);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, (int)(volume * audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)), 0);
}

private void resetVolumeSlider() {
// Resetting back to initial volume
Log.d(TAG, "RESET VOLUME TO: " + current_volume);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, (int)(current_volume), 0);
}
}
2 changes: 2 additions & 0 deletions src/ios/VolumeSlider.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -25,5 +25,7 @@
- (void)createVolumeSlider:(CDVInvokedUrlCommand *)command;
- (void)showVolumeSlider:(CDVInvokedUrlCommand *)command;
- (void)hideVolumeSlider:(CDVInvokedUrlCommand *)command;
- (void)setVolumeSlider:(CDVInvokedUrlCommand *)command;
- (void)resetVolumeSlider:(CDVInvokedUrlCommand *)command;

@end
45 changes: 43 additions & 2 deletions src/ios/VolumeSlider.m
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,6 +14,9 @@ @implementation VolumeSlider

@synthesize mpVolumeViewParentView, myVolumeView, callbackId;

float userVolume = 0.2;
UISlider* volumeViewSlider = nil;

#ifndef __IPHONE_3_0
@synthesize webView;
#endif
Expand All@@ -30,7 +33,8 @@ -(CDVPlugin*) initWithWebView:(UIWebView*)theWebView

- (void) createVolumeSlider:(CDVInvokedUrlCommand *)command
{
NSArray* arguments = [command arguments];
NSLog(@"In createVolumeSlider");
NSArray* arguments = [command arguments];

self.callbackId = command.callbackId;
NSUInteger argc = [arguments count];
Expand All@@ -40,7 +44,7 @@ - (void) createVolumeSlider:(CDVInvokedUrlCommand *)command
}

if (self.mpVolumeViewParentView != NULL) {
return;//already created, don't need to create it again
// return;//already created, don't need to create it again
}

CGFloat originx,originy,width;
Expand DownExpand Up@@ -68,12 +72,25 @@ - (void) createVolumeSlider:(CDVInvokedUrlCommand *)command
[[MPVolumeView alloc] initWithFrame: mpVolumeViewParentView.bounds];
[mpVolumeViewParentView addSubview: myVolumeView];
self.myVolumeView.showsVolumeSlider = NO;


volumeViewSlider = nil;
for (UIView *view in [self.myVolumeView subviews]){
if ([view.class.description isEqualToString:@"MPVolumeSlider"]){
volumeViewSlider = (UISlider*)view;
NSLog(@"Found MPVolumeslider : %f" ,userVolume );
break;
}
}
userVolume = volumeViewSlider.value;

}

- (void)showVolumeSlider:(CDVInvokedUrlCommand *)command
{
self.myVolumeView.showsVolumeSlider = YES;
self.mpVolumeViewParentView.hidden = NO;

}

- (void)hideVolumeSlider:(CDVInvokedUrlCommand *)command
Expand All@@ -82,6 +99,30 @@ - (void)hideVolumeSlider:(CDVInvokedUrlCommand *)command
self.myVolumeView.showsVolumeSlider = NO;
}

- (void)setVolumeSlider:(CDVInvokedUrlCommand *)command
{
self.mpVolumeViewParentView.hidden = YES;
self.myVolumeView.showsVolumeSlider = NO;

NSArray* arguments = [command arguments];
NSUInteger argc = [arguments count];

if (argc < 1) { // at a minimum we need the value to be set...
return;
}
float setVolume = [[arguments objectAtIndex:0] floatValue];

[volumeViewSlider setValue:setVolume animated:NO];
[volumeViewSlider sendActionsForControlEvents:UIControlEventTouchUpInside];

}

- (void)resetVolumeSlider:(CDVInvokedUrlCommand *)command
{
[volumeViewSlider setValue:userVolume animated:NO];
[volumeViewSlider sendActionsForControlEvents:UIControlEventTouchUpInside];

}


@end
18 changes: 16 additions & 2 deletions www/VolumeSlider.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@ var exec = require('cordova/exec');
module.exports = {

/**
* Create a volume slider.
* Create a volume slider, and save the user's current set volume.
*/
createVolumeSlider : function(originx,originy,width,height) {
exec(null, null, "VolumeSlider","createVolumeSlider", [originx, originy, width, height]);
Expand All@@ -31,5 +31,19 @@ module.exports = {
*/
hideVolumeSlider : function() {
exec(null, null, "VolumeSlider","hideVolumeSlider", []);
}
},

/**
* Set the device's master volume
*/
setVolumeSlider : function(set_volume) {
exec(null, null, "VolumeSlider","setVolumeSlider", [set_volume]);
},

/**
* Reset the volume slider to the original user volume present uon creation of this slider
*/
resetVolumeSlider : function() {
exec(null, null, "VolumeSlider","resetVolumeSlider", []);
}
};
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions plugin.xml
Original file line numberDiff line numberDiff line change
Expand Up@@ -32,5 +32,15 @@
<source-file src="src/ios/VolumeSlider.m" />
<framework src="MediaPlayer.framework" weak="true" />
</platform>

<!-- android -->
<platform name="android">
<config-file target="res/xml/config.xml" parent="/*">
<feature name="VolumeSlider">
<param name="android-package" value="org.devgeeks.volumeslider.VolumeSlider" />
</feature>
</config-file>

<source-file src="src/android/VolumeSlider.java" target-dir="src/org/devgeeks/volumeslider" />
</platform>
</plugin>
149 changes: 149 additions & 0 deletions src/android/VolumeSlider.java
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
package org.devgeeks.volumeslider;

import android.content.Context;
import android.media.AudioManager;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.SeekBar;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaArgs;
import org.apache.cordova.CordovaPlugin;
import org.json.JSONException;
import android.util.Log;

public class VolumeSlider extends CordovaPlugin {
private SeekBar volumeSeekBar;
private AudioManager audioManager;
private static final String TAG = "volume_slider";
double current_volume = 0.2;

private int cssToViewUnit(double size) {
return (int)Math.abs(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, (float)size,
cordova.getActivity().getResources().getDisplayMetrics()));
}

private double cssToViewUnitDouble(double size) {
return TypedValue.applyDimension(TypedValue.TYPE_NULL, (float)size,
cordova.getActivity().getResources().getDisplayMetrics());
}

@Override
public boolean execute(String action, CordovaArgs args, CallbackContext callbackContext) throws JSONException {
if (action == null)
return false;
if (action.equals("createVolumeSlider")) {
final int x = cssToViewUnit(args.getDouble(0));
final int y = cssToViewUnit(args.getDouble(1));
final int width = cssToViewUnit(args.getDouble(2));
final int height = cssToViewUnit(args.getDouble(3));
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
createVolumeSlider(x, y, width, height);
}
});
return true;
}
if (action.equals("showVolumeSlider")) {
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
showVolumeSlider();
}
});
return true;
}
if (action.equals("hideVolumeSlider")) {
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
hideVolumeSlider();
}
});
return true;
}
if (action.equals("setVolumeSlider")) {
final double volume = cssToViewUnitDouble(args.getDouble(0));
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
setVolumeSlider(volume);
}
});
return true;
}
if (action.equals("resetVolumeSlider")) {
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
resetVolumeSlider();
}
});
return true;
}
return false;
}

private void bindVolumeSeekBarToAudioManager(SeekBar volumeSeekBar, final Context context)
{
audioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
volumeSeekBar.setMax(audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC));
volumeSeekBar.setProgress(audioManager.getStreamVolume(AudioManager.STREAM_MUSIC));

volumeSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, progress, 0);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {}
});
}

private void createVolumeSlider(int x, int y, int width, int height) {
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(width, height);
params.leftMargin = x;
params.topMargin = y;

Context context = cordova.getActivity();

volumeSeekBar = new SeekBar(context);
bindVolumeSeekBarToAudioManager(volumeSeekBar, context);

// Record current media volume to revert to with resetVolumeSlider()
current_volume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
Log.d(TAG, "CURRENT VOLUME = " + current_volume);
hideVolumeSlider();

RelativeLayout layout = new RelativeLayout(context);
layout.addView(volumeSeekBar, params);
ViewGroup container = (ViewGroup)cordova.getActivity().findViewById(android.R.id.content);
container.addView(layout);
}

private void showVolumeSlider() {
volumeSeekBar.setVisibility(View.VISIBLE);
}

private void hideVolumeSlider() {
volumeSeekBar.setVisibility(View.INVISIBLE);
}

private void setVolumeSlider(double volume) {
// We map volume to a range of 0.0 - 1.0
Log.d(TAG, "SET VOLUME TO: " + volume);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, (int)(volume * audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)), 0);
}

private void resetVolumeSlider() {
// Resetting back to initial volume
Log.d(TAG, "RESET VOLUME TO: " + current_volume);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, (int)(current_volume), 0);
}
}
2 changes: 2 additions & 0 deletions src/ios/VolumeSlider.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -25,5 +25,7 @@
- (void)createVolumeSlider:(CDVInvokedUrlCommand *)command;
- (void)showVolumeSlider:(CDVInvokedUrlCommand *)command;
- (void)hideVolumeSlider:(CDVInvokedUrlCommand *)command;
- (void)setVolumeSlider:(CDVInvokedUrlCommand *)command;
- (void)resetVolumeSlider:(CDVInvokedUrlCommand *)command;

@end
45 changes: 43 additions & 2 deletions src/ios/VolumeSlider.m
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,6 +14,9 @@ @implementation VolumeSlider

@synthesize mpVolumeViewParentView, myVolumeView, callbackId;

float userVolume = 0.2;
UISlider* volumeViewSlider = nil;

#ifndef __IPHONE_3_0
@synthesize webView;
#endif
Expand All@@ -30,7 +33,8 @@ -(CDVPlugin*) initWithWebView:(UIWebView*)theWebView

- (void) createVolumeSlider:(CDVInvokedUrlCommand *)command
{
NSArray* arguments = [command arguments];
NSLog(@"In createVolumeSlider");
NSArray* arguments = [command arguments];

self.callbackId = command.callbackId;
NSUInteger argc = [arguments count];
Expand All@@ -40,7 +44,7 @@ - (void) createVolumeSlider:(CDVInvokedUrlCommand *)command
}

if (self.mpVolumeViewParentView != NULL) {
return;//already created, don't need to create it again
// return;//already created, don't need to create it again
}

CGFloat originx,originy,width;
Expand DownExpand Up@@ -68,12 +72,25 @@ - (void) createVolumeSlider:(CDVInvokedUrlCommand *)command
[[MPVolumeView alloc] initWithFrame: mpVolumeViewParentView.bounds];
[mpVolumeViewParentView addSubview: myVolumeView];
self.myVolumeView.showsVolumeSlider = NO;


volumeViewSlider = nil;
for (UIView *view in [self.myVolumeView subviews]){
if ([view.class.description isEqualToString:@"MPVolumeSlider"]){
volumeViewSlider = (UISlider*)view;
NSLog(@"Found MPVolumeslider : %f" ,userVolume );
break;
}
}
userVolume = volumeViewSlider.value;

}

- (void)showVolumeSlider:(CDVInvokedUrlCommand *)command
{
self.myVolumeView.showsVolumeSlider = YES;
self.mpVolumeViewParentView.hidden = NO;

}

- (void)hideVolumeSlider:(CDVInvokedUrlCommand *)command
Expand All@@ -82,6 +99,30 @@ - (void)hideVolumeSlider:(CDVInvokedUrlCommand *)command
self.myVolumeView.showsVolumeSlider = NO;
}

- (void)setVolumeSlider:(CDVInvokedUrlCommand *)command
{
self.mpVolumeViewParentView.hidden = YES;
self.myVolumeView.showsVolumeSlider = NO;

NSArray* arguments = [command arguments];
NSUInteger argc = [arguments count];

if (argc < 1) { // at a minimum we need the value to be set...
return;
}
float setVolume = [[arguments objectAtIndex:0] floatValue];

[volumeViewSlider setValue:setVolume animated:NO];
[volumeViewSlider sendActionsForControlEvents:UIControlEventTouchUpInside];

}

- (void)resetVolumeSlider:(CDVInvokedUrlCommand *)command
{
[volumeViewSlider setValue:userVolume animated:NO];
[volumeViewSlider sendActionsForControlEvents:UIControlEventTouchUpInside];

}


@end
18 changes: 16 additions & 2 deletions www/VolumeSlider.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@ var exec = require('cordova/exec');
module.exports = {

/**
* Create a volume slider.
* Create a volume slider, and save the user's current set volume.
*/
createVolumeSlider : function(originx,originy,width,height) {
exec(null, null, "VolumeSlider","createVolumeSlider", [originx, originy, width, height]);
Expand All@@ -31,5 +31,19 @@ module.exports = {
*/
hideVolumeSlider : function() {
exec(null, null, "VolumeSlider","hideVolumeSlider", []);
}
},

/**
* Set the device's master volume
*/
setVolumeSlider : function(set_volume) {
exec(null, null, "VolumeSlider","setVolumeSlider", [set_volume]);
},

/**
* Reset the volume slider to the original user volume present uon creation of this slider
*/
resetVolumeSlider : function() {
exec(null, null, "VolumeSlider","resetVolumeSlider", []);
}
};
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions plugin.xml
Original file line numberDiff line numberDiff line change
Expand Up@@ -32,5 +32,15 @@
<source-file src="src/ios/VolumeSlider.m" />
<framework src="MediaPlayer.framework" weak="true" />
</platform>

<!-- android -->
<platform name="android">
<config-file target="res/xml/config.xml" parent="/*">
<feature name="VolumeSlider">
<param name="android-package" value="org.devgeeks.volumeslider.VolumeSlider" />
</feature>
</config-file>

<source-file src="src/android/VolumeSlider.java" target-dir="src/org/devgeeks/volumeslider" />
</platform>
</plugin>
149 changes: 149 additions & 0 deletions src/android/VolumeSlider.java
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
package org.devgeeks.volumeslider;

import android.content.Context;
import android.media.AudioManager;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.SeekBar;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaArgs;
import org.apache.cordova.CordovaPlugin;
import org.json.JSONException;
import android.util.Log;

public class VolumeSlider extends CordovaPlugin {
private SeekBar volumeSeekBar;
private AudioManager audioManager;
private static final String TAG = "volume_slider";
double current_volume = 0.2;

private int cssToViewUnit(double size) {
return (int)Math.abs(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, (float)size,
cordova.getActivity().getResources().getDisplayMetrics()));
}

private double cssToViewUnitDouble(double size) {
return TypedValue.applyDimension(TypedValue.TYPE_NULL, (float)size,
cordova.getActivity().getResources().getDisplayMetrics());
}

@Override
public boolean execute(String action, CordovaArgs args, CallbackContext callbackContext) throws JSONException {
if (action == null)
return false;
if (action.equals("createVolumeSlider")) {
final int x = cssToViewUnit(args.getDouble(0));
final int y = cssToViewUnit(args.getDouble(1));
final int width = cssToViewUnit(args.getDouble(2));
final int height = cssToViewUnit(args.getDouble(3));
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
createVolumeSlider(x, y, width, height);
}
});
return true;
}
if (action.equals("showVolumeSlider")) {
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
showVolumeSlider();
}
});
return true;
}
if (action.equals("hideVolumeSlider")) {
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
hideVolumeSlider();
}
});
return true;
}
if (action.equals("setVolumeSlider")) {
final double volume = cssToViewUnitDouble(args.getDouble(0));
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
setVolumeSlider(volume);
}
});
return true;
}
if (action.equals("resetVolumeSlider")) {
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
resetVolumeSlider();
}
});
return true;
}
return false;
}

private void bindVolumeSeekBarToAudioManager(SeekBar volumeSeekBar, final Context context)
{
audioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
volumeSeekBar.setMax(audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC));
volumeSeekBar.setProgress(audioManager.getStreamVolume(AudioManager.STREAM_MUSIC));

volumeSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, progress, 0);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {}
});
}

private void createVolumeSlider(int x, int y, int width, int height) {
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(width, height);
params.leftMargin = x;
params.topMargin = y;

Context context = cordova.getActivity();

volumeSeekBar = new SeekBar(context);
bindVolumeSeekBarToAudioManager(volumeSeekBar, context);

// Record current media volume to revert to with resetVolumeSlider()
current_volume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
Log.d(TAG, "CURRENT VOLUME = " + current_volume);
hideVolumeSlider();

RelativeLayout layout = new RelativeLayout(context);
layout.addView(volumeSeekBar, params);
ViewGroup container = (ViewGroup)cordova.getActivity().findViewById(android.R.id.content);
container.addView(layout);
}

private void showVolumeSlider() {
volumeSeekBar.setVisibility(View.VISIBLE);
}

private void hideVolumeSlider() {
volumeSeekBar.setVisibility(View.INVISIBLE);
}

private void setVolumeSlider(double volume) {
// We map volume to a range of 0.0 - 1.0
Log.d(TAG, "SET VOLUME TO: " + volume);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, (int)(volume * audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)), 0);
}

private void resetVolumeSlider() {
// Resetting back to initial volume
Log.d(TAG, "RESET VOLUME TO: " + current_volume);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, (int)(current_volume), 0);
}
}
2 changes: 2 additions & 0 deletions src/ios/VolumeSlider.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -25,5 +25,7 @@
- (void)createVolumeSlider:(CDVInvokedUrlCommand *)command;
- (void)showVolumeSlider:(CDVInvokedUrlCommand *)command;
- (void)hideVolumeSlider:(CDVInvokedUrlCommand *)command;
- (void)setVolumeSlider:(CDVInvokedUrlCommand *)command;
- (void)resetVolumeSlider:(CDVInvokedUrlCommand *)command;

@end
45 changes: 43 additions & 2 deletions src/ios/VolumeSlider.m
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,6 +14,9 @@ @implementation VolumeSlider

@synthesize mpVolumeViewParentView, myVolumeView, callbackId;

float userVolume = 0.2;
UISlider* volumeViewSlider = nil;

#ifndef __IPHONE_3_0
@synthesize webView;
#endif
Expand All@@ -30,7 +33,8 @@ -(CDVPlugin*) initWithWebView:(UIWebView*)theWebView

- (void) createVolumeSlider:(CDVInvokedUrlCommand *)command
{
NSArray* arguments = [command arguments];
NSLog(@"In createVolumeSlider");
NSArray* arguments = [command arguments];

self.callbackId = command.callbackId;
NSUInteger argc = [arguments count];
Expand All@@ -40,7 +44,7 @@ - (void) createVolumeSlider:(CDVInvokedUrlCommand *)command
}

if (self.mpVolumeViewParentView != NULL) {
return;//already created, don't need to create it again
// return;//already created, don't need to create it again
}

CGFloat originx,originy,width;
Expand DownExpand Up@@ -68,12 +72,25 @@ - (void) createVolumeSlider:(CDVInvokedUrlCommand *)command
[[MPVolumeView alloc] initWithFrame: mpVolumeViewParentView.bounds];
[mpVolumeViewParentView addSubview: myVolumeView];
self.myVolumeView.showsVolumeSlider = NO;


volumeViewSlider = nil;
for (UIView *view in [self.myVolumeView subviews]){
if ([view.class.description isEqualToString:@"MPVolumeSlider"]){
volumeViewSlider = (UISlider*)view;
NSLog(@"Found MPVolumeslider : %f" ,userVolume );
break;
}
}
userVolume = volumeViewSlider.value;

}

- (void)showVolumeSlider:(CDVInvokedUrlCommand *)command
{
self.myVolumeView.showsVolumeSlider = YES;
self.mpVolumeViewParentView.hidden = NO;

}

- (void)hideVolumeSlider:(CDVInvokedUrlCommand *)command
Expand All@@ -82,6 +99,30 @@ - (void)hideVolumeSlider:(CDVInvokedUrlCommand *)command
self.myVolumeView.showsVolumeSlider = NO;
}

- (void)setVolumeSlider:(CDVInvokedUrlCommand *)command
{
self.mpVolumeViewParentView.hidden = YES;
self.myVolumeView.showsVolumeSlider = NO;

NSArray* arguments = [command arguments];
NSUInteger argc = [arguments count];

if (argc < 1) { // at a minimum we need the value to be set...
return;
}
float setVolume = [[arguments objectAtIndex:0] floatValue];

[volumeViewSlider setValue:setVolume animated:NO];
[volumeViewSlider sendActionsForControlEvents:UIControlEventTouchUpInside];

}

- (void)resetVolumeSlider:(CDVInvokedUrlCommand *)command
{
[volumeViewSlider setValue:userVolume animated:NO];
[volumeViewSlider sendActionsForControlEvents:UIControlEventTouchUpInside];

}


@end
18 changes: 16 additions & 2 deletions www/VolumeSlider.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@ var exec = require('cordova/exec');
module.exports = {

/**
* Create a volume slider.
* Create a volume slider, and save the user's current set volume.
*/
createVolumeSlider : function(originx,originy,width,height) {
exec(null, null, "VolumeSlider","createVolumeSlider", [originx, originy, width, height]);
Expand All@@ -31,5 +31,19 @@ module.exports = {
*/
hideVolumeSlider : function() {
exec(null, null, "VolumeSlider","hideVolumeSlider", []);
}
},

/**
* Set the device's master volume
*/
setVolumeSlider : function(set_volume) {
exec(null, null, "VolumeSlider","setVolumeSlider", [set_volume]);
},

/**
* Reset the volume slider to the original user volume present uon creation of this slider
*/
resetVolumeSlider : function() {
exec(null, null, "VolumeSlider","resetVolumeSlider", []);
}
};
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions plugin.xml
Original file line numberDiff line numberDiff line change
Expand Up@@ -32,5 +32,15 @@
<source-file src="src/ios/VolumeSlider.m" />
<framework src="MediaPlayer.framework" weak="true" />
</platform>

<!-- android -->
<platform name="android">
<config-file target="res/xml/config.xml" parent="/*">
<feature name="VolumeSlider">
<param name="android-package" value="org.devgeeks.volumeslider.VolumeSlider" />
</feature>
</config-file>

<source-file src="src/android/VolumeSlider.java" target-dir="src/org/devgeeks/volumeslider" />
</platform>
</plugin>
149 changes: 149 additions & 0 deletions src/android/VolumeSlider.java
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
package org.devgeeks.volumeslider;

import android.content.Context;
import android.media.AudioManager;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.SeekBar;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaArgs;
import org.apache.cordova.CordovaPlugin;
import org.json.JSONException;
import android.util.Log;

public class VolumeSlider extends CordovaPlugin {
private SeekBar volumeSeekBar;
private AudioManager audioManager;
private static final String TAG = "volume_slider";
double current_volume = 0.2;

private int cssToViewUnit(double size) {
return (int)Math.abs(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, (float)size,
cordova.getActivity().getResources().getDisplayMetrics()));
}

private double cssToViewUnitDouble(double size) {
return TypedValue.applyDimension(TypedValue.TYPE_NULL, (float)size,
cordova.getActivity().getResources().getDisplayMetrics());
}

@Override
public boolean execute(String action, CordovaArgs args, CallbackContext callbackContext) throws JSONException {
if (action == null)
return false;
if (action.equals("createVolumeSlider")) {
final int x = cssToViewUnit(args.getDouble(0));
final int y = cssToViewUnit(args.getDouble(1));
final int width = cssToViewUnit(args.getDouble(2));
final int height = cssToViewUnit(args.getDouble(3));
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
createVolumeSlider(x, y, width, height);
}
});
return true;
}
if (action.equals("showVolumeSlider")) {
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
showVolumeSlider();
}
});
return true;
}
if (action.equals("hideVolumeSlider")) {
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
hideVolumeSlider();
}
});
return true;
}
if (action.equals("setVolumeSlider")) {
final double volume = cssToViewUnitDouble(args.getDouble(0));
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
setVolumeSlider(volume);
}
});
return true;
}
if (action.equals("resetVolumeSlider")) {
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
resetVolumeSlider();
}
});
return true;
}
return false;
}

private void bindVolumeSeekBarToAudioManager(SeekBar volumeSeekBar, final Context context)
{
audioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
volumeSeekBar.setMax(audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC));
volumeSeekBar.setProgress(audioManager.getStreamVolume(AudioManager.STREAM_MUSIC));

volumeSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, progress, 0);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {}
});
}

private void createVolumeSlider(int x, int y, int width, int height) {
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(width, height);
params.leftMargin = x;
params.topMargin = y;

Context context = cordova.getActivity();

volumeSeekBar = new SeekBar(context);
bindVolumeSeekBarToAudioManager(volumeSeekBar, context);

// Record current media volume to revert to with resetVolumeSlider()
current_volume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
Log.d(TAG, "CURRENT VOLUME = " + current_volume);
hideVolumeSlider();

RelativeLayout layout = new RelativeLayout(context);
layout.addView(volumeSeekBar, params);
ViewGroup container = (ViewGroup)cordova.getActivity().findViewById(android.R.id.content);
container.addView(layout);
}

private void showVolumeSlider() {
volumeSeekBar.setVisibility(View.VISIBLE);
}

private void hideVolumeSlider() {
volumeSeekBar.setVisibility(View.INVISIBLE);
}

private void setVolumeSlider(double volume) {
// We map volume to a range of 0.0 - 1.0
Log.d(TAG, "SET VOLUME TO: " + volume);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, (int)(volume * audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)), 0);
}

private void resetVolumeSlider() {
// Resetting back to initial volume
Log.d(TAG, "RESET VOLUME TO: " + current_volume);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, (int)(current_volume), 0);
}
}
2 changes: 2 additions & 0 deletions src/ios/VolumeSlider.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -25,5 +25,7 @@
- (void)createVolumeSlider:(CDVInvokedUrlCommand *)command;
- (void)showVolumeSlider:(CDVInvokedUrlCommand *)command;
- (void)hideVolumeSlider:(CDVInvokedUrlCommand *)command;
- (void)setVolumeSlider:(CDVInvokedUrlCommand *)command;
- (void)resetVolumeSlider:(CDVInvokedUrlCommand *)command;

@end
45 changes: 43 additions & 2 deletions src/ios/VolumeSlider.m
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,6 +14,9 @@ @implementation VolumeSlider

@synthesize mpVolumeViewParentView, myVolumeView, callbackId;

float userVolume = 0.2;
UISlider* volumeViewSlider = nil;

#ifndef __IPHONE_3_0
@synthesize webView;
#endif
Expand All@@ -30,7 +33,8 @@ -(CDVPlugin*) initWithWebView:(UIWebView*)theWebView

- (void) createVolumeSlider:(CDVInvokedUrlCommand *)command
{
NSArray* arguments = [command arguments];
NSLog(@"In createVolumeSlider");
NSArray* arguments = [command arguments];

self.callbackId = command.callbackId;
NSUInteger argc = [arguments count];
Expand All@@ -40,7 +44,7 @@ - (void) createVolumeSlider:(CDVInvokedUrlCommand *)command
}

if (self.mpVolumeViewParentView != NULL) {
return;//already created, don't need to create it again
// return;//already created, don't need to create it again
}

CGFloat originx,originy,width;
Expand DownExpand Up@@ -68,12 +72,25 @@ - (void) createVolumeSlider:(CDVInvokedUrlCommand *)command
[[MPVolumeView alloc] initWithFrame: mpVolumeViewParentView.bounds];
[mpVolumeViewParentView addSubview: myVolumeView];
self.myVolumeView.showsVolumeSlider = NO;


volumeViewSlider = nil;
for (UIView *view in [self.myVolumeView subviews]){
if ([view.class.description isEqualToString:@"MPVolumeSlider"]){
volumeViewSlider = (UISlider*)view;
NSLog(@"Found MPVolumeslider : %f" ,userVolume );
break;
}
}
userVolume = volumeViewSlider.value;

}

- (void)showVolumeSlider:(CDVInvokedUrlCommand *)command
{
self.myVolumeView.showsVolumeSlider = YES;
self.mpVolumeViewParentView.hidden = NO;

}

- (void)hideVolumeSlider:(CDVInvokedUrlCommand *)command
Expand All@@ -82,6 +99,30 @@ - (void)hideVolumeSlider:(CDVInvokedUrlCommand *)command
self.myVolumeView.showsVolumeSlider = NO;
}

- (void)setVolumeSlider:(CDVInvokedUrlCommand *)command
{
self.mpVolumeViewParentView.hidden = YES;
self.myVolumeView.showsVolumeSlider = NO;

NSArray* arguments = [command arguments];
NSUInteger argc = [arguments count];

if (argc < 1) { // at a minimum we need the value to be set...
return;
}
float setVolume = [[arguments objectAtIndex:0] floatValue];

[volumeViewSlider setValue:setVolume animated:NO];
[volumeViewSlider sendActionsForControlEvents:UIControlEventTouchUpInside];

}

- (void)resetVolumeSlider:(CDVInvokedUrlCommand *)command
{
[volumeViewSlider setValue:userVolume animated:NO];
[volumeViewSlider sendActionsForControlEvents:UIControlEventTouchUpInside];

}


@end
18 changes: 16 additions & 2 deletions www/VolumeSlider.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@ var exec = require('cordova/exec');
module.exports = {

/**
* Create a volume slider.
* Create a volume slider, and save the user's current set volume.
*/
createVolumeSlider : function(originx,originy,width,height) {
exec(null, null, "VolumeSlider","createVolumeSlider", [originx, originy, width, height]);
Expand All@@ -31,5 +31,19 @@ module.exports = {
*/
hideVolumeSlider : function() {
exec(null, null, "VolumeSlider","hideVolumeSlider", []);
}
},

/**
* Set the device's master volume
*/
setVolumeSlider : function(set_volume) {
exec(null, null, "VolumeSlider","setVolumeSlider", [set_volume]);
},

/**
* Reset the volume slider to the original user volume present uon creation of this slider
*/
resetVolumeSlider : function() {
exec(null, null, "VolumeSlider","resetVolumeSlider", []);
}
};