Show qrcode for current server.
This commit is contained in:
@ -12,6 +12,7 @@ import Cocoa
|
||||
@NSApplicationMain
|
||||
class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDelegate {
|
||||
|
||||
var qrcodeWinCtrl: SWBQRCodeWindowController!
|
||||
var preferencesWinCtrl: PreferencesWindowController!
|
||||
var advPreferencesWinCtrl: AdvPreferencesWindowController!
|
||||
|
||||
@ -134,7 +135,33 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
|
||||
}
|
||||
|
||||
@IBAction func showQRCodeForCurrentServer(sender: NSMenuItem) {
|
||||
var errMsg: String?
|
||||
let mgr = ServerProfileManager()
|
||||
if let profile = mgr.getActiveProfile() {
|
||||
if profile.isValid() {
|
||||
// Show window
|
||||
if qrcodeWinCtrl != nil{
|
||||
qrcodeWinCtrl.close()
|
||||
}
|
||||
qrcodeWinCtrl = SWBQRCodeWindowController(windowNibName: "SWBQRCodeWindowController")
|
||||
qrcodeWinCtrl.qrCode = profile.URL()!.absoluteString
|
||||
qrcodeWinCtrl.showWindow(self)
|
||||
NSApp.activateIgnoringOtherApps(true)
|
||||
qrcodeWinCtrl.window?.makeKeyAndOrderFront(nil)
|
||||
|
||||
return
|
||||
} else {
|
||||
errMsg = "Current server profile is not valid.".localized
|
||||
}
|
||||
} else {
|
||||
errMsg = "No current server profile.".localized
|
||||
}
|
||||
let userNote = NSUserNotification()
|
||||
userNote.title = errMsg
|
||||
userNote.soundName = NSUserNotificationDefaultSoundName
|
||||
|
||||
NSUserNotificationCenter.defaultUserNotificationCenter()
|
||||
.deliverNotification(userNote);
|
||||
}
|
||||
|
||||
@IBAction func scanQRCodeFromScreen(sender: NSMenuItem) {
|
||||
|
@ -39,9 +39,15 @@
|
||||
<menuItem isSeparatorItem="YES" id="LXP-yK-yQu"/>
|
||||
<menuItem title="Auto Mode By PAC" id="hOa-5N-3ik">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="selectPACMode:" target="Voe-Tx-rLC" id="OwN-Md-pIC"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Global Mode" id="3Sa-e9-VXX">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="selectGlobalMode:" target="Voe-Tx-rLC" id="l4X-GP-hlH"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="kkf-gh-O8t"/>
|
||||
<menuItem title="Servers" id="u5M-hQ-VSc">
|
||||
|
17
ShadowsocksX-NG/SWBQRCodeWindowController.h
Normal file
17
ShadowsocksX-NG/SWBQRCodeWindowController.h
Normal file
@ -0,0 +1,17 @@
|
||||
//
|
||||
// QRCodeWindowController.h
|
||||
// shadowsocks
|
||||
//
|
||||
// Created by clowwindy on 10/12/14.
|
||||
// Copyright (c) 2014 clowwindy. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <WebKit/WebKit.h>
|
||||
|
||||
@interface SWBQRCodeWindowController : NSWindowController <WebFrameLoadDelegate>
|
||||
|
||||
@property (nonatomic, strong) IBOutlet WebView *webView;
|
||||
@property (nonatomic, copy) NSString *qrCode;
|
||||
|
||||
@end
|
35
ShadowsocksX-NG/SWBQRCodeWindowController.m
Normal file
35
ShadowsocksX-NG/SWBQRCodeWindowController.m
Normal file
@ -0,0 +1,35 @@
|
||||
//
|
||||
// QRCodeWindowController.m
|
||||
// shadowsocks
|
||||
//
|
||||
// Created by clowwindy on 10/12/14.
|
||||
// Copyright (c) 2014 clowwindy. All rights reserved.
|
||||
//
|
||||
|
||||
#import "SWBQRCodeWindowController.h"
|
||||
|
||||
@interface SWBQRCodeWindowController ()
|
||||
|
||||
@end
|
||||
|
||||
@implementation SWBQRCodeWindowController
|
||||
|
||||
- (void)windowDidLoad {
|
||||
[super windowDidLoad];
|
||||
|
||||
// Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
|
||||
[self.webView.mainFrame loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"qrcode" withExtension:@"htm"]]];
|
||||
self.webView.frameLoadDelegate = self;
|
||||
}
|
||||
|
||||
-(void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame {
|
||||
if (self.qrCode) {
|
||||
[self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"genCode('%@')", _qrCode]];
|
||||
}
|
||||
}
|
||||
|
||||
-(void)dealloc {
|
||||
self.webView.frameLoadDelegate = nil;
|
||||
}
|
||||
|
||||
@end
|
40
ShadowsocksX-NG/SWBQRCodeWindowController.xib
Normal file
40
ShadowsocksX-NG/SWBQRCodeWindowController.xib
Normal file
@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/>
|
||||
<plugIn identifier="com.apple.WebKitIBPlugin" version="10117"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="SWBQRCodeWindowController">
|
||||
<connections>
|
||||
<outlet property="webView" destination="ojI-LR-jEw" id="bpE-vv-uIe"/>
|
||||
<outlet property="window" destination="QvC-M9-y7g" id="HLy-eJ-5RD"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<window title="QR Code" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" oneShot="NO" animationBehavior="default" id="QvC-M9-y7g">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
|
||||
<rect key="contentRect" x="566" y="456" width="250" height="250"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
|
||||
<view key="contentView" id="EiT-Mj-1SZ">
|
||||
<rect key="frame" x="0.0" y="0.0" width="250" height="250"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<webView translatesAutoresizingMaskIntoConstraints="NO" id="ojI-LR-jEw">
|
||||
<rect key="frame" x="0.0" y="0.0" width="250" height="250"/>
|
||||
<webPreferences key="preferences" defaultFontSize="12" defaultFixedFontSize="12">
|
||||
<nil key="identifier"/>
|
||||
</webPreferences>
|
||||
</webView>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="ojI-LR-jEw" secondAttribute="trailing" id="ImJ-r1-FF9"/>
|
||||
<constraint firstAttribute="bottom" secondItem="ojI-LR-jEw" secondAttribute="bottom" id="LQv-2G-kyf"/>
|
||||
<constraint firstItem="ojI-LR-jEw" firstAttribute="leading" secondItem="EiT-Mj-1SZ" secondAttribute="leading" id="kok-J1-X08"/>
|
||||
<constraint firstItem="ojI-LR-jEw" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" id="voV-aN-Ggt"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</window>
|
||||
</objects>
|
||||
</document>
|
@ -93,6 +93,7 @@ class ServerProfile: NSObject {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
func validateDomainName(value: String) -> Bool {
|
||||
let validHostnameRegex = "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])$"
|
||||
|
||||
@ -113,4 +114,15 @@ class ServerProfile: NSObject {
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func URL() -> NSURL? {
|
||||
let parts = "\(method):\(password)@\(serverHost):\(serverPort)"
|
||||
let base64String = parts.dataUsingEncoding(NSUTF8StringEncoding)?
|
||||
.base64EncodedStringWithOptions(NSDataBase64EncodingOptions())
|
||||
if var s = base64String {
|
||||
s = s.stringByTrimmingCharactersInSet(NSCharacterSet(charactersInString: "="))
|
||||
return NSURL(string: "ss://\(s)")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
15
ShadowsocksX-NG/Sysconf.m
Normal file
15
ShadowsocksX-NG/Sysconf.m
Normal file
@ -0,0 +1,15 @@
|
||||
//
|
||||
// Sysconf.m
|
||||
// ShadowsocksX-NG
|
||||
//
|
||||
// Created by 邱宇舟 on 16/6/9.
|
||||
// Copyright © 2016年 qiuyuzhou. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <SystemConfiguration/SystemConfiguration.h>
|
||||
|
||||
|
||||
void ConfProxy() {
|
||||
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>com.qiuyuzhou.shadowsocksX-NE.local</string>
|
||||
<key>WorkingDirectory</key>
|
||||
<string>/Users/qiuyuzhou/</string>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/Users/qiuyuzhou/Library/Application Support/ShadowsocksX-NE/ss-local</string>
|
||||
<string>-c</string>
|
||||
<string>/Users/qiuyuzhou/Library/Application Support/ShadowsocksX-NE/ss-local-config.json</string>
|
||||
</array>
|
||||
<key>KeepAlive</key>
|
||||
<true/>
|
||||
<key>StandardOutPath</key>
|
||||
<string>/Users/qiuyuzhou/Library/Logs/ShadowsocksX-NE/ss-local.log</string>
|
||||
</dict>
|
||||
</plist>
|
2
ShadowsocksX-NG/jquery.min.js
vendored
Normal file
2
ShadowsocksX-NG/jquery.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
28
ShadowsocksX-NG/qrcode.htm
Normal file
28
ShadowsocksX-NG/qrcode.htm
Normal file
@ -0,0 +1,28 @@
|
||||
<!doctype html>
|
||||
<script src="jquery.min.js">
|
||||
</script>
|
||||
<script src="qrcode.min.js">
|
||||
</script>
|
||||
<style>
|
||||
body {
|
||||
padding: 10px;
|
||||
margin: 0;
|
||||
}
|
||||
#qrcode {
|
||||
width:230px;
|
||||
height:230px;
|
||||
}
|
||||
</style>
|
||||
<div id="qrcode"></div>
|
||||
<script type="text/javascript">
|
||||
function genCode(code) {
|
||||
new QRCode("qrcode", {
|
||||
text: code,
|
||||
width: 230,
|
||||
height: 230,
|
||||
colorDark : "#000000",
|
||||
colorLight : "#ffffff",
|
||||
correctLevel : QRCode.CorrectLevel.H
|
||||
});
|
||||
}
|
||||
</script>
|
1
ShadowsocksX-NG/qrcode.min.js
vendored
Normal file
1
ShadowsocksX-NG/qrcode.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user