35
+
36
+    private static boolean haveAddedDumpToAcra = false;
37
+
38
+    private static final String TAG = NikonGetLiveViewImageCommand.class.getSimpleName();
39
+    private static byte[] tmpStorage = new byte[0x4000];
40
+    private final Options options;
41
+    private LiveViewData data;
42
+
43
+    public NikonGetLiveViewImageCommand(NikonCamera camera, LiveViewData data) {
44
+        super(camera);
45
+        this.data = data;
46
+        if (data == null) {
47
+            this.data = new LiveViewData();
48
+            //this.data.histogram = ByteBuffer.allocate(1024 * 4);
49
+            //this.data.histogram.order(ByteOrder.LITTLE_ENDIAN);
50
+        } else {
51
+            this.data = data;
52
+        }
53
+        options = new BitmapFactory.Options();
54
+        options.inBitmap = this.data.bitmap;
55
+        options.inSampleSize = 1;
56
+        options.inTempStorage = tmpStorage;
57
+        this.data.bitmap = null;
58
+    }
59
+
60
+    @Override
61
+    public void exec(IO io) {
62
+        if (!camera.isLiveViewOpen()) {
63
+            return;
64
+        }
65
+        io.handleCommand(this);
66
+        if (responseCode == Response.DeviceBusy) {
67
+            camera.onDeviceBusy(this, true);
68
+            return;
69
+        }
70
+        data.hasHistogram = false;
71
+        if (this.data.bitmap != null && responseCode == Response.Ok) {
72
+            camera.onLiveViewReceived(data);
73
+        } else {
74
+            camera.onLiveViewReceived(null);
75
+        }
76
+    }
77
+
78
+    @Override
79
+    public void encodeCommand(ByteBuffer b) {
80
+        encodeCommand(b, Operation.NikonGetLiveViewImage);
81
+    }
82
+
83
+    @Override
84
+    protected void decodeData(ByteBuffer b, int length) {
85
+        if (length <= 128) {
86
+            return;
87
+        }
88
+
89
+        data.hasAfFrame = false;
90
+
91
+        int productId = camera.getProductId();
92
+        int start = b.position();
93
+        int pictureOffset;
94
+
95
+        switch (productId) {
96
+        case Product.NikonD5000:
97
+        case Product.NikonD3S:
98
+        case Product.NikonD90:
99
+            pictureOffset = 128;
100
+            break;
101
+        case Product.NikonD3X:
102
+        case Product.NikonD300S:
103
+        case Product.NikonD3:
104
+        case Product.NikonD300:
105
+        case Product.NikonD700:
106
+            pictureOffset = 64;
107
+            break;
108
+        case Product.NikonD7000:
109
+        case Product.NikonD5100:
110
+            pictureOffset = 384;
111
+            break;
112
+        default:
113
+            return;
114
+        }
115
+
116
+        b.order(ByteOrder.BIG_ENDIAN);
117
+
118
+        // read af frame
119
+        {
120
+            data.hasAfFrame = true;
121
+
122
+            int jpegImageWidth = b.getShort() & 0xFFFF;
123
+            int jpegImageHeight = b.getShort() & 0xFFFF;
124
+            int wholeWidth = b.getShort() & 0xFFFF;
125
+            int wholeHeight = b.getShort() & 0xFFFF;
126
+
127
+            float multX = jpegImageWidth / (float) wholeWidth;
128
+            float multY = jpegImageHeight / (float) wholeHeight;
129
+
130
+            b.position(start + 16);
131
+            data.nikonWholeWidth = wholeWidth;
132
+            data.nikonWholeHeight = wholeHeight;
133
+            data.nikonAfFrameWidth = (int) ((b.getShort() & 0xFFFF) * multX);
134
+            data.nikonAfFrameHeight = (int) ((b.getShort() & 0xFFFF) * multY);
135
+            data.nikonAfFrameCenterX = (int) ((b.getShort() & 0xFFFF) * multX);
136
+            data.nikonAfFrameCenterY = (int) ((b.getShort() & 0xFFFF) * multY);
137
+        }
138
+
139
+        b.order(ByteOrder.LITTLE_ENDIAN);
140
+
141
+        b.position(start + pictureOffset);
142
+
143
+        if (b.remaining() <= 128) {
144
+            data.bitmap = null;
145
+            return;
146
+        }
147
+
148
+        try {
149
+            data.bitmap = BitmapFactory.decodeByteArray(b.array(), b.position(), length - b.position(), options);
150
+        } catch (RuntimeException e) {
151
+            Log.e(TAG, "decoding failed " + e.toString());
152
+            Log.e(TAG, e.getLocalizedMessage());
153
+            if (AppConfig.LOG) {
154
+                PacketUtil.logHexdump(TAG, b.array(), start, 512);
155
+            }
156
+        }
157
+    }
158
+}

+ 51 - 0
ryc/src/main/java/com/remoteyourcam/usb/ptp/commands/nikon/NikonGetVendorPropCodesCommand.java

@@ -0,0 +1,51 @@
1
+/**
2
+ * Copyright 2013 Nils Assbeck, Guersel Ayaz and Michael Zoech
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ *     http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+package com.remoteyourcam.usb.ptp.commands.nikon;
17
+
18
+import java.nio.ByteBuffer;
19
+
20
+import com.remoteyourcam.usb.ptp.NikonCamera;
21
+import com.remoteyourcam.usb.ptp.PacketUtil;
22
+import com.remoteyourcam.usb.ptp.PtpCamera.IO;
23
+import com.remoteyourcam.usb.ptp.PtpConstants.Operation;
24
+
25
+public class NikonGetVendorPropCodesCommand extends NikonCommand {
26
+
27
+    private int[] propertyCodes = new int[0];
28
+
29
+    public NikonGetVendorPropCodesCommand(NikonCamera camera) {
30
+        super(camera);
31
+    }
32
+
33
+    public int[] getPropertyCodes() {
34
+        return propertyCodes;
35
+    }
36
+
37
+    @Override
38
+    public void exec(IO io) {
39
+        throw new UnsupportedOperationException();
40
+    }
41
+
42
+    @Override
43
+    public void encodeCommand(ByteBuffer b) {
44
+        encodeCommand(b, Operation.NikonGetVendorPropCodes);
45
+    }
46
+
47
+    @Override
48
+    protected void decodeData(ByteBuffer b, int length) {
49
+        propertyCodes = PacketUtil.readU16Array(b);
50
+    }
51
+}

+ 69 - 0
ryc/src/main/java/com/remoteyourcam/usb/ptp/commands/nikon/NikonOpenSessionAction.java

@@ -0,0 +1,69 @@
1
+/**
2
+ * Copyright 2013 Nils Assbeck, Guersel Ayaz and Michael Zoech
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ *     http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+package com.remoteyourcam.usb.ptp.commands.nikon;
17
+
18
+import com.remoteyourcam.usb.ptp.NikonCamera;
19
+import com.remoteyourcam.usb.ptp.PtpAction;
20
+import com.remoteyourcam.usb.ptp.PtpCamera.IO;
21
+import com.remoteyourcam.usb.ptp.PtpConstants;
22
+import com.remoteyourcam.usb.ptp.PtpConstants.Datatype;
23
+import com.remoteyourcam.usb.ptp.PtpConstants.Operation;
24
+import com.remoteyourcam.usb.ptp.PtpConstants.Property;
25
+import com.remoteyourcam.usb.ptp.commands.OpenSessionCommand;
26
+import com.remoteyourcam.usb.ptp.commands.SetDevicePropValueCommand;
27
+
28
+public class NikonOpenSessionAction implements PtpAction {
29
+
30
+    private final NikonCamera camera;
31
+
32
+    public NikonOpenSessionAction(NikonCamera camera) {
33
+        this.camera = camera;
34
+    }
35
+
36
+    @Override
37
+    public void exec(IO io) {
38
+        OpenSessionCommand openSession = new OpenSessionCommand(camera);
39
+        io.handleCommand(openSession);
40
+        if (openSession.getResponseCode() == PtpConstants.Response.Ok) {
41
+            if (camera.hasSupportForOperation(Operation.NikonGetVendorPropCodes)) {
42
+                NikonGetVendorPropCodesCommand getPropCodes = new NikonGetVendorPropCodesCommand(camera);
43
+                io.handleCommand(getPropCodes);
44
+                SetDevicePropValueCommand c = new SetDevicePropValueCommand(camera, Property.NikonRecordingMedia, 1,
45
+                        Datatype.uint8);
46
+                io.handleCommand(c);
47
+                if (getPropCodes.getResponseCode() == PtpConstants.Response.Ok
48
+                        && c.getResponseCode() == PtpConstants.Response.Ok) {
49
+                    camera.setVendorPropCodes(getPropCodes.getPropertyCodes());
50
+                    camera.onSessionOpened();
51
+                } else {
52
+                    camera.onPtpError(String.format(
53
+                            "Couldn't read device property codes! Open session command failed with error code \"%s\"",
54
+                            PtpConstants.responseToString(getPropCodes.getResponseCode())));
55
+                }
56
+            } else {
57
+                camera.onSessionOpened();
58
+            }
59
+        } else {
60
+            camera.onPtpError(String.format(
61
+                    "Couldn't open session! Open session command failed with error code \"%s\"",
62
+                    PtpConstants.responseToString(openSession.getResponseCode())));
63
+        }
64
+    }
65
+
66
+    @Override
67
+    public void reset() {
68
+    }
69
+}

+ 66 - 0
ryc/src/main/java/com/remoteyourcam/usb/ptp/commands/nikon/NikonStartLiveViewAction.java

@@ -0,0 +1,66 @@
1
+/**
2
+ * Copyright 2013 Nils Assbeck, Guersel Ayaz and Michael Zoech
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ *     http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+package com.remoteyourcam.usb.ptp.commands.nikon;
17
+
18
+import com.remoteyourcam.usb.ptp.NikonCamera;
19
+import com.remoteyourcam.usb.ptp.PtpAction;
20
+import com.remoteyourcam.usb.ptp.PtpCamera.IO;
21
+import com.remoteyourcam.usb.ptp.PtpConstants.Operation;
22
+import com.remoteyourcam.usb.ptp.PtpConstants.Response;
23
+import com.remoteyourcam.usb.ptp.commands.SimpleCommand;
24
+
25
+public class NikonStartLiveViewAction implements PtpAction {
26
+
27
+    private final NikonCamera camera;
28
+
29
+    public NikonStartLiveViewAction(NikonCamera camera) {
30
+        this.camera = camera;
31
+    }
32
+
33
+    @Override
34
+    public void exec(IO io) {
35
+        SimpleCommand simpleCmd = new SimpleCommand(camera, Operation.NikonStartLiveView);
36
+        io.handleCommand(simpleCmd);
37
+
38
+        if (simpleCmd.getResponseCode() != Response.Ok) {
39
+            return;
40
+        }
41
+
42
+        SimpleCommand deviceReady = new SimpleCommand(camera, Operation.NikonDeviceReady);
43
+        for (int i = 0; i < 10; ++i) {
44
+            try {
45
+                Thread.sleep(300);
46
+            } catch (InterruptedException e) {
47
+                // nop
48
+            }
49
+
50
+            deviceReady.reset();
51
+            io.handleCommand(deviceReady);
52
+            if (deviceReady.getResponseCode() == Response.DeviceBusy) {
53
+                // still waiting
54
+            } else if (deviceReady.getResponseCode() == Response.Ok) {
55
+                camera.onLiveViewStarted();
56
+                return;
57
+            } else {
58
+                return;
59
+            }
60
+        }
61
+    }
62
+
63
+    @Override
64
+    public void reset() {
65
+    }
66
+}

+ 54 - 0
ryc/src/main/java/com/remoteyourcam/usb/ptp/commands/nikon/NikonStopLiveViewAction.java

@@ -0,0 +1,54 @@
1
+/**
2
+ * Copyright 2013 Nils Assbeck, Guersel Ayaz and Michael Zoech
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ *     http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+package com.remoteyourcam.usb.ptp.commands.nikon;
17
+
18
+import com.remoteyourcam.usb.ptp.NikonCamera;
19
+import com.remoteyourcam.usb.ptp.PtpAction;
20
+import com.remoteyourcam.usb.ptp.PtpCamera.IO;
21
+import com.remoteyourcam.usb.ptp.PtpConstants.Operation;
22
+import com.remoteyourcam.usb.ptp.PtpConstants.Response;
23
+import com.remoteyourcam.usb.ptp.commands.SimpleCommand;
24
+
25
+public class NikonStopLiveViewAction implements PtpAction {
26
+
27
+    private final NikonCamera camera;
28
+    private final boolean notifyUser;
29
+
30
+    public NikonStopLiveViewAction(NikonCamera camera, boolean notifyUser) {
31
+        this.camera = camera;
32
+        this.notifyUser = notifyUser;
33
+    }
34
+
35
+    @Override
36
+    public void exec(IO io) {
37
+        SimpleCommand simpleCmd = new SimpleCommand(camera, Operation.NikonEndLiveView);
38
+        io.handleCommand(simpleCmd);
39
+
40
+        if (simpleCmd.getResponseCode() == Response.DeviceBusy) {
41
+            camera.onDeviceBusy(this, true);
42
+        } else {
43
+            if (notifyUser) {
44
+                camera.onLiveViewStopped();
45
+            } else {
46
+                camera.onLiveViewStoppedInternal();
47
+            }
48
+        }
49
+    }
50
+
51
+    @Override
52
+    public void reset() {
53
+    }
54
+}

+ 113 - 0
ryc/src/main/java/com/remoteyourcam/usb/ptp/model/DeviceInfo.java

@@ -0,0 +1,113 @@
1
+/**
2
+ * Copyright 2013 Nils Assbeck, Guersel Ayaz and Michael Zoech
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ *     http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+package com.remoteyourcam.usb.ptp.model;
17
+
18
+import java.nio.ByteBuffer;
19
+import java.util.Arrays;
20
+
21
+import com.remoteyourcam.usb.ptp.PacketUtil;
22
+import com.remoteyourcam.usb.ptp.PtpConstants;
23
+
24
+/**
25
+ * Device info data set as defined by PTP standard.
26
+ */
27
+public class DeviceInfo {
28
+
29
+    public short standardVersion;
30
+    public int vendorExtensionId;
31
+    public short vendorExtensionVersion;
32
+    public String vendorExtensionDesc;
33
+    public short functionalMode;
34
+    public int[] operationsSupported;
35
+    public int[] eventsSupported;
36
+    public int[] devicePropertiesSupported;
37
+    public int[] captureFormats;
38
+    public int[] imageFormats;
39
+    public String manufacture;
40
+    public String model;
41
+    public String deviceVersion;
42
+    public String serialNumber;
43
+
44
+    public DeviceInfo(ByteBuffer b, int length) {
45
+        decode(b, length);
46
+    }
47
+
48
+    public DeviceInfo() {
49
+    }
50
+
51
+    public void decode(ByteBuffer b, int length) {
52
+        standardVersion = b.getShort();
53
+        vendorExtensionId = b.getInt();
54
+        vendorExtensionVersion = b.getShort();
55
+        vendorExtensionDesc = PacketUtil.readString(b);
56
+        functionalMode = b.getShort();
57
+        operationsSupported = PacketUtil.readU16Array(b);
58
+        eventsSupported = PacketUtil.readU16Array(b);
59
+        devicePropertiesSupported = PacketUtil.readU16Array(b);
60
+        captureFormats = PacketUtil.readU16Array(b);
61
+        imageFormats = PacketUtil.readU16Array(b);
62
+        manufacture = PacketUtil.readString(b);
63
+        model = PacketUtil.readString(b);
64
+        deviceVersion = PacketUtil.readString(b);
65
+        serialNumber = PacketUtil.readString(b);
66
+    }
67
+
68
+    public void encode(ByteBuffer b) {
69
+        b.putShort(standardVersion);
70
+        b.putInt(vendorExtensionId);
71
+        b.putInt(vendorExtensionVersion);
72
+        PacketUtil.writeString(b, "");
73
+        b.putShort(functionalMode);
74
+        PacketUtil.writeU16Array(b, new int[0]);
75
+        PacketUtil.writeU16Array(b, new int[0]);
76
+        PacketUtil.writeU16Array(b, new int[0]);
77
+        PacketUtil.writeU16Array(b, new int[0]);
78
+        PacketUtil.writeU16Array(b, new int[0]);
79
+        PacketUtil.writeString(b, "");
80
+        PacketUtil.writeString(b, "");
81
+        PacketUtil.writeString(b, "");
82
+    }
83
+
84
+    @Override
85
+    public String toString() {
86
+        // Changes here have to reflect changes in PtpConstants.main()
87
+        StringBuilder b = new StringBuilder();
88
+        b.append("DeviceInfo\n");
89
+        b.append("StandardVersion: ").append(standardVersion).append('\n');
90
+        b.append("VendorExtensionId: ").append(vendorExtensionId).append('\n');
91
+        b.append("VendorExtensionVersion: ").append(vendorExtensionVersion).append('\n');
92
+        b.append("VendorExtensionDesc: ").append(vendorExtensionDesc).append('\n');
93
+        b.append("FunctionalMode: ").append(functionalMode).append('\n');
94
+        appendU16Array(b, "OperationsSupported", PtpConstants.Operation.class, operationsSupported);
95
+        appendU16Array(b, "EventsSupported", PtpConstants.Event.class, eventsSupported);
96
+        appendU16Array(b, "DevicePropertiesSupported", PtpConstants.Property.class, devicePropertiesSupported);
97
+        appendU16Array(b, "CaptureFormats", PtpConstants.ObjectFormat.class, captureFormats);
98
+        appendU16Array(b, "ImageFormats", PtpConstants.ObjectFormat.class, imageFormats);
99
+        b.append("Manufacture: ").append(manufacture).append('\n');
100
+        b.append("Model: ").append(model).append('\n');
101
+        b.append("DeviceVersion: ").append(deviceVersion).append('\n');
102
+        b.append("SerialNumber: ").append(serialNumber).append('\n');
103
+        return b.toString();
104
+    }
105
+
106
+    private static void appendU16Array(StringBuilder b, String name, Class<?> cl, int[] a) {
107
+        Arrays.sort(a);
108
+        b.append(name).append(":\n");
109
+        for (int i = 0; i < a.length; ++i) {
110
+            b.append("    ").append(PtpConstants.constantToString(cl, a[i])).append('\n');
111
+        }
112
+    }
113
+}

+ 102 - 0
ryc/src/main/java/com/remoteyourcam/usb/ptp/model/DevicePropDesc.java

@@ -0,0 +1,102 @@
1
+/**
2
+ * Copyright 2013 Nils Assbeck, Guersel Ayaz and Michael Zoech
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ *     http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+package com.remoteyourcam.usb.ptp.model;
17
+
18
+import java.nio.ByteBuffer;
19
+
20
+import com.remoteyourcam.usb.ptp.PacketUtil;
21
+import com.remoteyourcam.usb.ptp.PtpConstants.Datatype;
22
+
23
+public class DevicePropDesc {
24
+
25
+    public int code;
26
+    public int datatype;
27
+    public boolean readOnly;
28
+    public int factoryDefault;
29
+    public int currentValue;
30
+    public int[] description;
31
+
32
+    public DevicePropDesc() {
33
+    }
34
+
35
+    public DevicePropDesc(ByteBuffer b, int length) {
36
+        decode(b, length);
37
+    }
38
+
39
+    public void decode(ByteBuffer b, int length) {
40
+        code = b.getShort() & 0xFFFF;
41
+        datatype = b.getShort() & 0xFFFF;
42
+        readOnly = b.get() == 0;
43
+
44
+        if (datatype == Datatype.int8 || datatype == Datatype.uint8) {
45
+            factoryDefault = b.get() & 0xFF;
46
+            currentValue = b.get() & 0xFF;
47
+            int form = b.get();
48
+            if (form == 2) {
49
+                description = PacketUtil.readU8Enumeration(b);
50
+            } else if (form == 1) {
51
+                int mini = b.get();
52
+                int maxi = b.get();
53
+                int step = b.get();
54
+                description = new int[(maxi - mini) / step + 1];
55
+                for (int i = 0; i < description.length; ++i) {
56
+                    description[i] = mini + step * i;
57
+                }
58
+            }
59
+        } else if (datatype == Datatype.uint16) {
60
+            factoryDefault = b.getShort() & 0xFFFF;
61
+            currentValue = b.getShort() & 0xFFFF;
62
+            int form = b.get();
63
+            if (form == 2) {
64
+                description = PacketUtil.readU16Enumeration(b);
65
+            } else if (form == 1) {
66
+                int mini = b.getShort() & 0xFFFF;
67
+                int maxi = b.getShort() & 0xFFFF;
68
+                int step = b.getShort() & 0xFFFF;
69
+                description = new int[(maxi - mini) / step + 1];
70
+                for (int i = 0; i < description.length; ++i) {
71
+                    description[i] = mini + step * i;
72
+                }
73
+            }
74
+        } else if (datatype == Datatype.int16) {
75
+            factoryDefault = b.getShort();
76
+            currentValue = b.getShort();
77
+            int form = b.get();
78
+            if (form == 2) {
79
+                description = PacketUtil.readS16Enumeration(b);
80
+            } else if (form == 1) {
81
+                int mini = b.getShort();
82
+                int maxi = b.getShort();
83
+                int step = b.getShort();
84
+                description = new int[(maxi - mini) / step + 1];
85
+                for (int i = 0; i < description.length; ++i) {
86
+                    description[i] = mini + step * i;
87
+                }
88
+            }
89
+        } else if (datatype == Datatype.int32 || datatype == Datatype.uint32) {
90
+            factoryDefault = b.getInt();
91
+            currentValue = b.getInt();
92
+            int form = b.get();
93
+            if (form == 2) {
94
+                description = PacketUtil.readU32Enumeration(b);
95
+            }
96
+        }
97
+
98
+        if (description == null) {
99
+            description = new int[0];
100
+        }
101
+    }
102
+}

+ 44 - 0
ryc/src/main/java/com/remoteyourcam/usb/ptp/model/LiveViewData.java

@@ -0,0 +1,44 @@
1
+/**
2
+ * Copyright 2013 Nils Assbeck, Guersel Ayaz and Michael Zoech
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ *     http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+package com.remoteyourcam.usb.ptp.model;
17
+
18
+import java.nio.ByteBuffer;
19
+
20
+import android.graphics.Bitmap;
21
+
22
+public class LiveViewData {
23
+
24
+    public Bitmap bitmap;
25
+
26
+    public int zoomFactor;
27
+    public int zoomRectLeft;
28
+    public int zoomRectTop;
29
+    public int zoomRectRight;
30
+    public int zoomRectBottom;
31
+
32
+    public boolean hasHistogram;
33
+    public ByteBuffer histogram;
34
+
35
+    // dimensions are in bitmap size
36
+    public boolean hasAfFrame;
37
+    public int nikonAfFrameCenterX;
38
+    public int nikonAfFrameCenterY;
39
+    public int nikonAfFrameWidth;
40
+    public int nikonAfFrameHeight;
41
+
42
+    public int nikonWholeWidth;
43
+    public int nikonWholeHeight;
44
+}

+ 101 - 0
ryc/src/main/java/com/remoteyourcam/usb/ptp/model/ObjectInfo.java

@@ -0,0 +1,101 @@
1
+/**
2
+ * Copyright 2013 Nils Assbeck, Guersel Ayaz and Michael Zoech
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ *     http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+package com.remoteyourcam.usb.ptp.model;
17
+
18
+import java.nio.ByteBuffer;
19
+
20
+import com.remoteyourcam.usb.ptp.PacketUtil;
21
+import com.remoteyourcam.usb.ptp.PtpConstants;
22
+
23
+/**
24
+ * Object info data set as defined by the PTP standard.
25
+ */
26
+public class ObjectInfo {
27
+
28
+    public int storageId;
29
+    public int objectFormat;
30
+    public int protectionStatus;
31
+    public int objectCompressedSize;
32
+    public int thumbFormat;
33
+    public int thumbCompressedSize;
34
+    public int thumbPixWidth;
35
+    public int thumbPixHeight;
36
+    public int imagePixWidth;
37
+    public int imagePixHeight;
38
+    public int imageBitDepth;
39
+    public int parentObject;
40
+    public int associationType;
41
+    public int associationDesc;
42
+    public int sequenceNumber;
43
+    public String filename;
44
+    public String captureDate;
45
+    public String modificationDate;
46
+    public int keywords;
47
+
48
+    public ObjectInfo() {
49
+    }
50
+
51
+    public ObjectInfo(ByteBuffer b, int length) {
52
+        decode(b, length);
53
+    }
54
+
55
+    public void decode(ByteBuffer b, int length) {
56
+        storageId = b.getInt();
57
+        objectFormat = b.getShort();
58
+        protectionStatus = b.getShort();
59
+        objectCompressedSize = b.getInt();
60
+        thumbFormat = b.getShort();
61
+        thumbCompressedSize = b.getInt();
62
+        thumbPixWidth = b.getInt();
63
+        thumbPixHeight = b.getInt();
64
+        imagePixWidth = b.getInt();
65
+        imagePixHeight = b.getInt();
66
+        imageBitDepth = b.getInt();
67
+        parentObject = b.getInt();
68
+        associationType = b.getShort();
69
+        associationDesc = b.getInt();
70
+        sequenceNumber = b.getInt();
71
+        filename = PacketUtil.readString(b);
72
+        captureDate = PacketUtil.readString(b);
73
+        modificationDate = PacketUtil.readString(b);
74
+        keywords = b.get(); // string, not used on camera?
75
+    }
76
+
77
+    @Override
78
+    public String toString() {
79
+        StringBuilder b = new StringBuilder();
80
+        b.append("ObjectInfo\n");
81
+        b.append("StorageId: ").append(String.format("0x%08x\n", storageId));
82
+        b.append("ObjectFormat: ").append(PtpConstants.objectFormatToString(objectFormat)).append('\n');
83
+        b.append("ProtectionStatus: ").append(protectionStatus).append('\n');
84
+        b.append("ObjectCompressedSize: ").append(objectCompressedSize).append('\n');
85
+        b.append("ThumbFormat: ").append(PtpConstants.objectFormatToString(thumbFormat)).append('\n');
86
+        b.append("ThumbCompressedSize: ").append(thumbCompressedSize).append('\n');
87
+        b.append("ThumbPixWdith: ").append(thumbPixWidth).append('\n');
88
+        b.append("ThumbPixHeight: ").append(thumbPixHeight).append('\n');
89
+        b.append("ImagePixWidth: ").append(imagePixWidth).append('\n');
90
+        b.append("ImagePixHeight: ").append(imagePixHeight).append('\n');
91
+        b.append("ImageBitDepth: ").append(imageBitDepth).append('\n');
92
+        b.append("ParentObject: ").append(String.format("0x%08x", parentObject)).append('\n');
93
+        b.append("AssociationType: ").append(associationType).append('\n');
94
+        b.append("AssociatonDesc: ").append(associationDesc).append('\n');
95
+        b.append("Filename: ").append(filename).append('\n');
96
+        b.append("CaptureDate: ").append(captureDate).append('\n');
97
+        b.append("ModificationDate: ").append(modificationDate).append('\n');
98
+        b.append("Keywords: ").append(keywords).append('\n');
99
+        return b.toString();
100
+    }
101
+}

+ 47 - 0
ryc/src/main/java/com/remoteyourcam/usb/ptp/model/StorageInfo.java

@@ -0,0 +1,47 @@
1
+/**
2
+ * Copyright 2013 Nils Assbeck, Guersel Ayaz and Michael Zoech
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ *     http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+package com.remoteyourcam.usb.ptp.model;
17
+
18
+import java.nio.ByteBuffer;
19
+
20
+import com.remoteyourcam.usb.ptp.PacketUtil;
21
+
22
+public class StorageInfo {
23
+
24
+    public int storageType;
25
+    public int filesystemType;
26
+    public int accessCapability;
27
+    public long maxCapacity;
28
+    public long freeSpaceInBytes;
29
+    public int freeSpaceInImages;
30
+    public String storageDescription;
31
+    public String volumeLabel;
32
+
33
+    public StorageInfo(ByteBuffer b, int length) {
34
+        decode(b, length);
35
+    }
36
+
37
+    private void decode(ByteBuffer b, int length) {
38
+        storageType = b.getShort() & 0xffff;
39
+        filesystemType = b.getShort() & 0xffff;
40
+        accessCapability = b.getShort() & 0xff;
41
+        maxCapacity = b.getLong();
42
+        freeSpaceInBytes = b.getLong();
43
+        freeSpaceInImages = b.getInt();
44
+        storageDescription = PacketUtil.readString(b);
45
+        volumeLabel = PacketUtil.readString(b);
46
+    }
47
+}

+ 3 - 0
ryc/src/main/res/values/strings.xml

@@ -0,0 +1,3 @@
1
+<resources>
2
+    <string name="app_name">ryc</string>
3
+</resources>

+ 1 - 1
settings.gradle

@@ -1 +1 @@
1
-include ':app', ':common', ':views'
1
+include ':app', ':common', ':views', ':ryc'

extend param to_uid for comment_submit_api · fa36c26ce4 - Gogs: Go Git Service

extend param to_uid for comment_submit_api

Brightcells 9 anni fa
parent
commit
fa36c26ce4
4 ha cambiato i file con 25 aggiunte e 2 eliminazioni
  1. 2 2
      group/admin.py
  2. 19 0
      group/migrations/0021_photocommentinfo_to_uid.py
  3. 2 0
      group/models.py
  4. 2 0
      group/views.py

+ 2 - 2
group/admin.py

@@ -26,12 +26,12 @@ class GroupPhotoOrderInfoAdmin(admin.ModelAdmin):
26 26
 
27 27
 
28 28
 class PhotoCommentInfoAdmin(admin.ModelAdmin):
29
-    list_display = ('photo_id', 'user_id', 'nickname', 'avatar', 'comment', 'status', 'created_at', 'updated_at')
29
+    list_display = ('photo_id', 'user_id', 'nickname', 'to_uid', 'comment', 'status', 'created_at', 'updated_at')
30 30
     list_filter = ('status', )
31 31
 
32 32
 
33 33
 class PhotoThumbUpInfoAdmin(admin.ModelAdmin):
34
-    list_display = ('photo_id', 'user_id', 'nickname', 'avatar', 'thumbup', 'status', 'created_at', 'updated_at')
34
+    list_display = ('photo_id', 'user_id', 'nickname', 'thumbup', 'status', 'created_at', 'updated_at')
35 35
     list_filter = ('thumbup', 'status')
36 36
 
37 37
 

+ 19 - 0
group/migrations/0021_photocommentinfo_to_uid.py

@@ -0,0 +1,19 @@
1
+# -*- coding: utf-8 -*-
2
+from __future__ import unicode_literals
3
+
4
+from django.db import models, migrations
5
+
6
+
7
+class Migration(migrations.Migration):
8
+
9
+    dependencies = [
10
+        ('group', '0020_groupphotoinfo_session_id'),
11
+    ]
12
+
13
+    operations = [
14
+        migrations.AddField(
15
+            model_name='photocommentinfo',
16
+            name='to_uid',
17
+            field=models.CharField(max_length=255, blank=True, help_text='\u88ab\u8bc4\u8bba\u7528\u6237\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='to_uid', db_index=True),
18
+        ),
19
+    ]

+ 2 - 0
group/models.py

@@ -271,6 +271,7 @@ class PhotoCommentInfo(CreateUpdateMixin):
271 271
     user_id = models.CharField(_(u'user_id'), max_length=255, blank=True, null=True, help_text=u'用户唯一标识', db_index=True)
272 272
     nickname = models.CharField(_(u'nickname'), max_length=255, blank=True, null=True, help_text=u'用户群组昵称')
273 273
     avatar = models.CharField(_(u'avatar'), max_length=255, blank=True, null=True, help_text=u'用户头像')
274
+    to_uid = models.CharField(_(u'to_uid'), max_length=255, blank=True, null=True, help_text=u'被评论用户唯一标识', db_index=True)
274 275
     comment = models.TextField(_(u'comment'), blank=True, null=True, help_text=u'用户评论')
275 276
 
276 277
     class Meta:
@@ -286,6 +287,7 @@ class PhotoCommentInfo(CreateUpdateMixin):
286 287
             'user_id': self.user_id,
287 288
             'nickname': self.nickname,
288 289
             'avatar': self.avatar,
290
+            'to_uid': self.to_uid,
289 291
             'comment': self.comment,
290 292
             'created_at': self.created_at.replace(microsecond=0),
291 293
         }

+ 2 - 0
group/views.py

@@ -638,6 +638,7 @@ def comment_submit_api(request):
638 638
     """
639 639
     group_id = request.POST.get('group_id', '')
640 640
     user_id = request.POST.get('user_id', '')
641
+    to_uid = request.POST.get('to_uid', '')
641 642
     photo_id = request.POST.get('photo_id', '')
642 643
     comment = request.POST.get('comment', '')
643 644
 
@@ -660,6 +661,7 @@ def comment_submit_api(request):
660 661
             user_id=user_id,
661 662
             nickname=group_user.nickname,
662 663
             avatar=group_user.avatar,
664
+            to_uid=to_uid,
663 665
             comment=comment,
664 666
         )
665 667
 

PullToRefresh kvo issue · 65bedd3c66 - Gogs: Go Git Service

PullToRefresh kvo issue

FFIB 6 年之前
父節點
當前提交
65bedd3c66
共有 21 個文件被更改,包括 160 次插入112 次删除
  1. 56 24
      PaiAi/Paiai.xcodeproj/project.pbxproj
  2. 二進制
      PaiAi/Paiai.xcodeproj/project.xcworkspace/xcuserdata/FFIB.xcuserdatad/UserInterfaceState.xcuserstate
  3. 1 0
      PaiAi/Paiai/AppDelegate.swift
  4. 4 0
      PaiAi/Paiai/Info.plist
  5. 1 0
      PaiAi/PaiaiDataKit/DataLayer/Repositories/Remote/Reusable/NetWork/NetworkApi.swift
  6. 3 3
      PaiAi/PaiaiDataKit/DataLayer/Repositories/Remote/WXUserInfoRemoteAPI.swift
  7. 3 7
      PaiAi/PaiaiDataKit/PresentLayer/UserInfoViewModel.swift
  8. 0 16
      PaiAi/PaiaiUIKit/Reusable/UIKit/AlertViewController/Default/AlertAction/CancelAlertAction.swift
  9. 0 16
      PaiAi/PaiaiUIKit/Reusable/UIKit/AlertViewController/Default/AlertAction/ConfirmAlertAction.swift
  10. 0 16
      PaiAi/PaiaiUIKit/Reusable/UIKit/AlertViewController/Default/AlertAction/DestructiveAlertAction.swift
  11. 1 1
      PaiAi/PaiaiUIKit/Reusable/UIKit/NavigationBack/GestureRecoginzier+NavigationBack.swift
  12. 33 20
      PaiAi/PaiaiUIKit/Reusable/UIKit/NavigationBar/NavigationBarInOutAnimator.swift
  13. 5 4
      PaiAi/PaiaiUIKit/Reusable/UIKit/NavigationBar/NavigationBarInteractivePopDeletegate.swift
  14. 4 4
      PaiAi/PaiaiUIKit/Reusable/UIKit/NavigationBar/NavigationBarPushAndPopDelegate.swift
  15. 29 0
      PaiAi/PaiaiUIKit/Reusable/UIKit/NavigationController/NavigationController.swift
  16. 0 1
      PaiAi/PaiaiUIKit/Reusable/UIKit/PageViewController/PageViewController.swift
  17. 4 0
      PaiAi/Paiai_iOS/App/Group/GroupViewController.swift
  18. 4 0
      PaiAi/Paiai_iOS/App/Home/HomeViewController.swift
  19. 4 0
      PaiAi/Paiai_iOS/App/Message/MessageListViewController.swift
  20. 4 0
      PaiAi/Paiai_iOS/App/Mine/MineGroupViewController.swift
  21. 4 0
      PaiAi/Paiai_iOS/App/Mine/MineOrderViewController.swift

+ 56 - 24
PaiAi/Paiai.xcodeproj/project.pbxproj

@@ -3,7 +3,7 @@
3 3
 	archiveVersion = 1;
4 4
 	classes = {
5 5
 	};
6
-	objectVersion = 46;
6
+	objectVersion = 51;
7 7
 	objects = {
8 8
 
9 9
 /* Begin PBXBuildFile section */
@@ -38,6 +38,7 @@
38 38
 		050D719B22531B860076CE06 /* RxSwift.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 050D719A22531B860076CE06 /* RxSwift.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
39 39
 		050D719D22531BA60076CE06 /* SQLite.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 050D719C22531BA60076CE06 /* SQLite.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
40 40
 		050D719E22531BBF0076CE06 /* Differentiator.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 05130FBD21CA194B004EF1BE /* Differentiator.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
41
+		050D71A322545D550076CE06 /* NavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 050D71A222545D550076CE06 /* NavigationController.swift */; };
41 42
 		05130F4021C94B33004EF1BE /* PaiaiUIKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 05130F3021C94B32004EF1BE /* PaiaiUIKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
42 43
 		05130F5721C94C12004EF1BE /* AlertAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05130F4F21C94C12004EF1BE /* AlertAnimator.swift */; };
43 44
 		05130F5921C94C12004EF1BE /* AlertViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05130F5121C94C12004EF1BE /* AlertViewController.swift */; };
@@ -147,10 +148,7 @@
147 148
 		0513106721CA290B004EF1BE /* DateExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0543274721C68C1900C6388D /* DateExt.swift */; };
148 149
 		0513106921CA34D6004EF1BE /* GroupDetailCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0513106821CA34D6004EF1BE /* GroupDetailCoordinator.swift */; };
149 150
 		0513106B21CA3545004EF1BE /* PhotoDetailCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0513106A21CA3545004EF1BE /* PhotoDetailCoordinator.swift */; };
150
-		0513107D21CA3907004EF1BE /* CancelAlertAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0513106F21CA3907004EF1BE /* CancelAlertAction.swift */; };
151
-		0513107F21CA3907004EF1BE /* DestructiveAlertAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0513107121CA3907004EF1BE /* DestructiveAlertAction.swift */; };
152 151
 		0513108021CA3907004EF1BE /* ActionSheetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0513107221CA3907004EF1BE /* ActionSheetView.swift */; };
153
-		0513108121CA3907004EF1BE /* ConfirmAlertAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0513107321CA3907004EF1BE /* ConfirmAlertAction.swift */; };
154 152
 		0513109321CA3915004EF1BE /* ColorQR.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0513108A21CA3914004EF1BE /* ColorQR.swift */; };
155 153
 		0513109421CA3915004EF1BE /* QRCodeMaskView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0513108B21CA3914004EF1BE /* QRCodeMaskView.swift */; };
156 154
 		0513109521CA3915004EF1BE /* QRCodeScanDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0513108C21CA3914004EF1BE /* QRCodeScanDelegate.swift */; };
@@ -347,6 +345,7 @@
347 345
 		050D719822531B780076CE06 /* RxCocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RxCocoa.framework; path = Carthage/Build/iOS/RxCocoa.framework; sourceTree = "<group>"; };
348 346
 		050D719A22531B860076CE06 /* RxSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RxSwift.framework; path = Carthage/Build/iOS/RxSwift.framework; sourceTree = "<group>"; };
349 347
 		050D719C22531BA60076CE06 /* SQLite.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SQLite.framework; path = Carthage/Build/iOS/SQLite.framework; sourceTree = "<group>"; };
348
+		050D71A222545D550076CE06 /* NavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationController.swift; sourceTree = "<group>"; };
350 349
 		050E210F21B8CE8A008E1352 /* AppCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCoordinator.swift; sourceTree = "<group>"; };
351 350
 		050E211121B8F2D4008E1352 /* HomeCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeCoordinator.swift; sourceTree = "<group>"; };
352 351
 		050E211321B8F39C008E1352 /* MineCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MineCoordinator.swift; sourceTree = "<group>"; };
@@ -389,10 +388,7 @@
389 388
 		0513106121CA22B5004EF1BE /* Alamofire.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Alamofire.framework; path = Carthage/Build/iOS/Alamofire.framework; sourceTree = "<group>"; };
390 389
 		0513106821CA34D6004EF1BE /* GroupDetailCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupDetailCoordinator.swift; sourceTree = "<group>"; };
391 390
 		0513106A21CA3545004EF1BE /* PhotoDetailCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoDetailCoordinator.swift; sourceTree = "<group>"; };
392
-		0513106F21CA3907004EF1BE /* CancelAlertAction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CancelAlertAction.swift; sourceTree = "<group>"; };
393
-		0513107121CA3907004EF1BE /* DestructiveAlertAction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DestructiveAlertAction.swift; sourceTree = "<group>"; };
394 391
 		0513107221CA3907004EF1BE /* ActionSheetView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetView.swift; sourceTree = "<group>"; };
395
-		0513107321CA3907004EF1BE /* ConfirmAlertAction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConfirmAlertAction.swift; sourceTree = "<group>"; };
396 392
 		0513108A21CA3914004EF1BE /* ColorQR.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColorQR.swift; sourceTree = "<group>"; };
397 393
 		0513108B21CA3914004EF1BE /* QRCodeMaskView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QRCodeMaskView.swift; sourceTree = "<group>"; };
398 394
 		0513108C21CA3914004EF1BE /* QRCodeScanDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QRCodeScanDelegate.swift; sourceTree = "<group>"; };
@@ -649,6 +645,14 @@
649 645
 			path = Animationes;
650 646
 			sourceTree = "<group>";
651 647
 		};
648
+		050D71A122545CE20076CE06 /* NavigationController */ = {
649
+			isa = PBXGroup;
650
+			children = (
651
+				050D71A222545D550076CE06 /* NavigationController.swift */,
652
+			);
653
+			path = NavigationController;
654
+			sourceTree = "<group>";
655
+		};
652 656
 		05130F2F21C94B32004EF1BE /* PaiaiUIKit */ = {
653 657
 			isa = PBXGroup;
654 658
 			children = (
@@ -675,6 +679,7 @@
675 679
 		05130F4D21C94B72004EF1BE /* UIKit */ = {
676 680
 			isa = PBXGroup;
677 681
 			children = (
682
+				050D71A122545CE20076CE06 /* NavigationController */,
678 683
 				055BB53F220AEA4E009548AA /* Nibless */,
679 684
 				0584FD7A21FABA0300FA1E3E /* Present */,
680 685
 				05C8D21E21EDD5A80001E847 /* NavigationBar */,
@@ -1058,9 +1063,6 @@
1058 1063
 				057317A321F5C6C0009B2FCE /* BottomCancelItem.swift */,
1059 1064
 				059B58A721F83B1600FA64C2 /* CenterCancelItem.swift */,
1060 1065
 				059B58A921F83B2E00FA64C2 /* CenterConfirmItem.swift */,
1061
-				0513106F21CA3907004EF1BE /* CancelAlertAction.swift */,
1062
-				0513107121CA3907004EF1BE /* DestructiveAlertAction.swift */,
1063
-				0513107321CA3907004EF1BE /* ConfirmAlertAction.swift */,
1064 1066
 			);
1065 1067
 			path = AlertAction;
1066 1068
 			sourceTree = "<group>";
@@ -1294,6 +1296,7 @@
1294 1296
 				7737858CEE753530C312F2CB /* Frameworks */,
1295 1297
 			);
1296 1298
 			sourceTree = "<group>";
1299
+			usesTabs = 0;
1297 1300
 		};
1298 1301
 		6CEBD1001CA8D680004DBDE0 /* Products */ = {
1299 1302
 			isa = PBXGroup;
@@ -1484,7 +1487,7 @@
1484 1487
 			attributes = {
1485 1488
 				LastSwiftUpdateCheck = 1010;
1486 1489
 				LastUpgradeCheck = 1020;
1487
-				ORGANIZATIONNAME = yb;
1490
+				ORGANIZATIONNAME = FFIB;
1488 1491
 				TargetAttributes = {
1489 1492
 					05130F2D21C94B32004EF1BE = {
1490 1493
 						CreatedOnToolsVersion = 10.1;
@@ -1524,7 +1527,7 @@
1524 1527
 				};
1525 1528
 			};
1526 1529
 			buildConfigurationList = 6CEBD0FA1CA8D680004DBDE0 /* Build configuration list for PBXProject "Paiai" */;
1527
-			compatibilityVersion = "Xcode 3.2";
1530
+			compatibilityVersion = "Xcode 10.0";
1528 1531
 			developmentRegion = en;
1529 1532
 			hasScannedForEncodings = 0;
1530 1533
 			knownRegions = (
@@ -1627,7 +1630,6 @@
1627 1630
 				05C8D21D21EDD3770001E847 /* NavigationBarInteractivePopDeletegate.swift in Sources */,
1628 1631
 				05C8D22421EED92F0001E847 /* NavigationBarPushAndPopDelegate.swift in Sources */,
1629 1632
 				05130FFD21CA1B39004EF1BE /* HardwareAuthorization.swift in Sources */,
1630
-				0513107D21CA3907004EF1BE /* CancelAlertAction.swift in Sources */,
1631 1633
 				05130FFE21CA1B39004EF1BE /* WaterfallFlowLayout.swift in Sources */,
1632 1634
 				05130FFF21CA1B39004EF1BE /* WaterfallFlowConfiguration.swift in Sources */,
1633 1635
 				055BB53E220AEA3B009548AA /* NiblessViewController.swift in Sources */,
@@ -1639,12 +1641,10 @@
1639 1641
 				0513100121CA1B39004EF1BE /* CGPointExt.swift in Sources */,
1640 1642
 				0584FD7521F9C70D00FA1E3E /* SideAnimator.swift in Sources */,
1641 1643
 				0584FD7721F9C8A300FA1E3E /* PresentAnimatorDelegate.swift in Sources */,
1642
-				0513107F21CA3907004EF1BE /* DestructiveAlertAction.swift in Sources */,
1643 1644
 				059B589F21F7103100FA64C2 /* AlertItem.swift in Sources */,
1644 1645
 				059B58A621F7235D00FA64C2 /* AlertAction.swift in Sources */,
1645 1646
 				0513109821CA3915004EF1BE /* QRCodeScanResult.swift in Sources */,
1646 1647
 				0513100221CA1B39004EF1BE /* CGSizeExt.swift in Sources */,
1647
-				0513108121CA3907004EF1BE /* ConfirmAlertAction.swift in Sources */,
1648 1648
 				05C8D22221EED6860001E847 /* NavigationBarInteractiveViewController.swift in Sources */,
1649 1649
 				0513109A21CA3915004EF1BE /* QRCodeScanView.swift in Sources */,
1650 1650
 				0513100721CA1B39004EF1BE /* UIViewController+UIBarButtonItem.swift in Sources */,
@@ -1671,6 +1671,7 @@
1671 1671
 				0513101921CA1B39004EF1BE /* UIImageExt.swift in Sources */,
1672 1672
 				05C8D22921EF0A9F0001E847 /* NavigationControllerProxy.swift in Sources */,
1673 1673
 				05D3A3D02200288400A29A20 /* Storyboarded.swift in Sources */,
1674
+				050D71A322545D550076CE06 /* NavigationController.swift in Sources */,
1674 1675
 				05C0CEFB21F85A7700993DE2 /* ActionSheetController.swift in Sources */,
1675 1676
 				05C8D21421ED8B9B0001E847 /* NavigationBackViewController.swift in Sources */,
1676 1677
 				0584FD7C21FABC1400FA1E3E /* PresentExtension.swift in Sources */,
@@ -1937,7 +1938,11 @@
1937 1938
 				INFOPLIST_FILE = PaiaiUIKit/Info.plist;
1938 1939
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
1939 1940
 				IPHONEOS_DEPLOYMENT_TARGET = 10.0;
1940
-				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
1941
+				LD_RUNPATH_SEARCH_PATHS = (
1942
+					"$(inherited)",
1943
+					"@executable_path/Frameworks",
1944
+					"@loader_path/Frameworks",
1945
+				);
1941 1946
 				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
1942 1947
 				MTL_FAST_MATH = YES;
1943 1948
 				PRODUCT_BUNDLE_IDENTIFIER = FFIB.PaiaiUIKit;
@@ -1973,7 +1978,11 @@
1973 1978
 				INFOPLIST_FILE = PaiaiUIKit/Info.plist;
1974 1979
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
1975 1980
 				IPHONEOS_DEPLOYMENT_TARGET = 10.0;
1976
-				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
1981
+				LD_RUNPATH_SEARCH_PATHS = (
1982
+					"$(inherited)",
1983
+					"@executable_path/Frameworks",
1984
+					"@loader_path/Frameworks",
1985
+				);
1977 1986
 				MTL_FAST_MATH = YES;
1978 1987
 				PRODUCT_BUNDLE_IDENTIFIER = FFIB.PaiaiUIKit;
1979 1988
 				PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
@@ -2013,7 +2022,11 @@
2013 2022
 				INFOPLIST_FILE = PaiaiDataKit/Info.plist;
2014 2023
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
2015 2024
 				IPHONEOS_DEPLOYMENT_TARGET = 10.0;
2016
-				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
2025
+				LD_RUNPATH_SEARCH_PATHS = (
2026
+					"$(inherited)",
2027
+					"@executable_path/Frameworks",
2028
+					"@loader_path/Frameworks",
2029
+				);
2017 2030
 				LIBRARY_SEARCH_PATHS = (
2018 2031
 					"$(inherited)",
2019 2032
 					"$(PROJECT_DIR)/Paiai/wxSDK",
@@ -2062,7 +2075,11 @@
2062 2075
 				INFOPLIST_FILE = PaiaiDataKit/Info.plist;
2063 2076
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
2064 2077
 				IPHONEOS_DEPLOYMENT_TARGET = 10.0;
2065
-				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
2078
+				LD_RUNPATH_SEARCH_PATHS = (
2079
+					"$(inherited)",
2080
+					"@executable_path/Frameworks",
2081
+					"@loader_path/Frameworks",
2082
+				);
2066 2083
 				LIBRARY_SEARCH_PATHS = (
2067 2084
 					"$(inherited)",
2068 2085
 					"$(PROJECT_DIR)/Paiai/wxSDK",
@@ -2104,7 +2121,11 @@
2104 2121
 				INFOPLIST_FILE = Paiai_iOS/Info.plist;
2105 2122
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
2106 2123
 				IPHONEOS_DEPLOYMENT_TARGET = 10.0;
2107
-				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
2124
+				LD_RUNPATH_SEARCH_PATHS = (
2125
+					"$(inherited)",
2126
+					"@executable_path/Frameworks",
2127
+					"@loader_path/Frameworks",
2128
+				);
2108 2129
 				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
2109 2130
 				MTL_FAST_MATH = YES;
2110 2131
 				PRODUCT_BUNDLE_IDENTIFIER = "com.Paiai-iOS";
@@ -2144,7 +2165,11 @@
2144 2165
 				INFOPLIST_FILE = Paiai_iOS/Info.plist;
2145 2166
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
2146 2167
 				IPHONEOS_DEPLOYMENT_TARGET = 10.0;
2147
-				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
2168
+				LD_RUNPATH_SEARCH_PATHS = (
2169
+					"$(inherited)",
2170
+					"@executable_path/Frameworks",
2171
+					"@loader_path/Frameworks",
2172
+				);
2148 2173
 				MTL_FAST_MATH = YES;
2149 2174
 				PRODUCT_BUNDLE_IDENTIFIER = "com.Paiai-iOS";
2150 2175
 				PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
@@ -2267,7 +2292,8 @@
2267 2292
 					"-all_load",
2268 2293
 				);
2269 2294
 				SDKROOT = iphoneos;
2270
-				SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
2295
+				SWIFT_COMPILATION_MODE = wholemodule;
2296
+				SWIFT_OPTIMIZATION_LEVEL = "-O";
2271 2297
 				VALIDATE_PRODUCT = YES;
2272 2298
 			};
2273 2299
 			name = Release;
@@ -2301,7 +2327,10 @@
2301 2327
 				);
2302 2328
 				INFOPLIST_FILE = PaiAi/Info.plist;
2303 2329
 				IPHONEOS_DEPLOYMENT_TARGET = 10.0;
2304
-				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
2330
+				LD_RUNPATH_SEARCH_PATHS = (
2331
+					"$(inherited)",
2332
+					"@executable_path/Frameworks",
2333
+				);
2305 2334
 				LIBRARY_SEARCH_PATHS = (
2306 2335
 					"$(inherited)",
2307 2336
 					"$(PROJECT_DIR)/Paiai/wxSDK",
@@ -2348,7 +2377,10 @@
2348 2377
 				);
2349 2378
 				INFOPLIST_FILE = PaiAi/Info.plist;
2350 2379
 				IPHONEOS_DEPLOYMENT_TARGET = 10.0;
2351
-				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
2380
+				LD_RUNPATH_SEARCH_PATHS = (
2381
+					"$(inherited)",
2382
+					"@executable_path/Frameworks",
2383
+				);
2352 2384
 				LIBRARY_SEARCH_PATHS = (
2353 2385
 					"$(inherited)",
2354 2386
 					"$(PROJECT_DIR)/Paiai/wxSDK",

二進制
PaiAi/Paiai.xcodeproj/project.xcworkspace/xcuserdata/FFIB.xcuserdatad/UserInterfaceState.xcuserstate


+ 1 - 0
PaiAi/Paiai/AppDelegate.swift

@@ -34,6 +34,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, WXApiDelegate {
34 34
             let rootViewController = ContainerViewController()
35 35
             let nav = UINavigationController(rootViewController: rootViewController)
36 36
             
37
+            rootViewController.setupNavigationBarPushAndPopDelegate()
37 38
             window = UIWindow(frame: UIScreen.main.bounds)
38 39
             window?.rootViewController = nav
39 40
             window?.makeKeyAndVisible()

+ 4 - 0
PaiAi/Paiai/Info.plist

@@ -25,6 +25,8 @@
25 25
 		<dict>
26 26
 			<key>CFBundleTypeRole</key>
27 27
 			<string>Editor</string>
28
+			<key>CFBundleURLName</key>
29
+			<string>weixin</string>
28 30
 			<key>CFBundleURLSchemes</key>
29 31
 			<array>
30 32
 				<string>wx4e22a0c8ae6d766d</string>
@@ -43,6 +45,8 @@
43 45
 		<dict>
44 46
 			<key>CFBundleTypeRole</key>
45 47
 			<string>Editor</string>
48
+			<key>CFBundleURLName</key>
49
+			<string>weibo</string>
46 50
 			<key>CFBundleURLSchemes</key>
47 51
 			<array>
48 52
 				<string>wb2730190333</string>

+ 1 - 0
PaiAi/PaiaiDataKit/DataLayer/Repositories/Remote/Reusable/NetWork/NetworkApi.swift

@@ -74,6 +74,7 @@ class NetworkApi {
74 74
                         if status == 200 {
75 75
                             observer(.success(data))
76 76
                         } else {
77
+                            print(json)
77 78
                             Toast.show(message: (json["description"]  as? String) ?? "")
78 79
                             observer(.error(BusinessError(id: status)))
79 80
                         }

+ 3 - 3
PaiAi/PaiaiDataKit/DataLayer/Repositories/Remote/WXUserInfoRemoteAPI.swift

@@ -17,12 +17,12 @@ struct WXUserInfoRemoteAPI: UserInfoRemoteAPI {
17 17
     init() {}
18 18
     
19 19
     func login() -> Single<UserInfo> {
20
-        #if (arch(i386) || arch(x86_64))
20
+//        #if (arch(i386) || arch(x86_64))
21 21
         return Single.create(subscribe: { (observer) in
22 22
             observer(.success(UserInfo(json: ["user_id": "fiDz2Ms" as AnyObject, "userName": "郑剑飞" as AnyObject, "photoPath": "https://wx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTJibSYLgvXpMakvD9FaCqfiaWqcMiaiaz905YxWPuO4hy8F2lGheV7kVr9vKKXFgmL1S5s4QJgxwuwtVw/132" as AnyObject])))
23 23
             return Disposables.create()
24 24
         })
25
-        #else
25
+//        #else
26 26
         loginWithWeChat()
27 27
         return addWXLoginDidFinish().flatMap({
28 28
             return self.getWXToken(param: $0)
@@ -33,7 +33,7 @@ struct WXUserInfoRemoteAPI: UserInfoRemoteAPI {
33 33
         }).do(onSuccess: { res in
34 34
             print(res)
35 35
         })
36
-        #endif
36
+//        #endif
37 37
     }
38 38
     
39 39
     fileprivate func loginWithWeChat() {

+ 3 - 7
PaiAi/PaiaiDataKit/PresentLayer/UserInfoViewModel.swift

@@ -71,9 +71,7 @@ public class UserInfoViewModel {
71 71
         repository.guestLogin().subscribe(onSuccess: { (userInfo) in
72 72
             self.shareUserInfo.accept(userInfo)
73 73
             self._loginCompleted.onNext(())
74
-        }) { (error) in
75
-            #warning("错误处理")
76
-        }.disposed(by: disposeBag)
74
+        }).disposed(by: disposeBag)
77 75
     }
78 76
     
79 77
     public func wxLogin() {
@@ -81,10 +79,8 @@ public class UserInfoViewModel {
81 79
         repository.wxLogin().subscribe(onSuccess: { (userInfo) in
82 80
             self.shareUserInfo.accept(userInfo)
83 81
             self._loginCompleted.onNext(())
84
-        }) { (error) in
85
-            print(error)
86
-            #warning("错误处理")
87
-        }.disposed(by: disposeBag)
82
+            Toast.hide()
83
+        }).disposed(by: disposeBag)
88 84
     }
89 85
     
90 86
     deinit {

+ 0 - 16
PaiAi/PaiaiUIKit/Reusable/UIKit/AlertViewController/Default/AlertAction/CancelAlertAction.swift

@@ -1,16 +0,0 @@
1
-//
2
-//  CancelAlertAction.swift
3
-//  PaiAi
4
-//
5
-//  Created by FFIB on 2017/11/20.
6
-//  Copyright © 2017年 yb. All rights reserved.
7
-//
8
-
9
-import UIKit
10
-//
11
-//class CancelAlertAction: FFAlertAction {
12
-//    init() {
13
-//        super.init(attributedTitle: NSAttributedString(string: "取消", attributes: [NSAttributedString.Key.foregroundColor: UIColor(r: 51, g: 51, b: 51)]),
14
-//                   backgroundColor: UIColor(r: 222, g: 222, b: 222), handler: nil)
15
-//    }
16
-//}

+ 0 - 16
PaiAi/PaiaiUIKit/Reusable/UIKit/AlertViewController/Default/AlertAction/ConfirmAlertAction.swift

@@ -1,16 +0,0 @@
1
-//
2
-//  ConfirmAlertAction.swift
3
-//  PaiAi
4
-//
5
-//  Created by FFIB on 2017/11/20.
6
-//  Copyright © 2017年 yb. All rights reserved.
7
-//
8
-
9
-import UIKit
10
-
11
-//class ConfirmAlertAction: FFAlertAction {
12
-//    init(title: String = "确定", handler: ((FFAlertAction) -> Void)?) {
13
-//        super.init(attributedTitle: NSAttributedString(string: title, attributes: [NSAttributedString.Key.foregroundColor: UIColor.white]),
14
-//                   backgroundColor: UIColor(r: 129, g: 209, b: 53), handler: handler)
15
-//    }
16
-//}

+ 0 - 16
PaiAi/PaiaiUIKit/Reusable/UIKit/AlertViewController/Default/AlertAction/DestructiveAlertAction.swift

@@ -1,16 +0,0 @@
1
-//
2
-//  DestructiveAlertAction.swift
3
-//  PaiAi
4
-//
5
-//  Created by FFIB on 2017/11/20.
6
-//  Copyright © 2017年 yb. All rights reserved.
7
-//
8
-
9
-import UIKit
10
-
11
-//class DestructiveAlertAction: FFAlertAction {
12
-//    init(title: String, handler: ((FFAlertAction) -> Void)?) {
13
-//        super.init(attributedTitle: NSAttributedString(string: title, attributes: [NSAttributedString.Key.foregroundColor: UIColor(r: 248, g: 86, b: 131)]),
14
-//                   backgroundColor: UIColor.white, handler: handler)
15
-//    }
16
-//}

+ 1 - 1
PaiAi/PaiaiUIKit/Reusable/UIKit/NavigationBack/GestureRecoginzier+NavigationBack.swift

@@ -15,7 +15,7 @@ public extension GestureRecognizerDelegate where Self: UIViewController & Naviga
15 15
             gestureRecognizer.isKind(of: UIPanGestureRecognizer.self),
16 16
             let pan = gestureRecognizer as? UIPanGestureRecognizer {
17 17
             let point = pan.translation(in: self.view)
18
-            if point.x > 30 {
18
+            if point.x > 0 {
19 19
                 return true
20 20
             }
21 21
         }

+ 33 - 20
PaiAi/PaiaiUIKit/Reusable/UIKit/NavigationBar/NavigationBarInOutAnimator.swift

@@ -10,46 +10,59 @@ import UIKit
10 10
 
11 11
 public protocol NavigationBarInOutAnimator: class {
12 12
     var navigationView: UIView { get }
13
-    func navigationBarFadeIn()
14
-    func navigationBarFadeOut()
15
-    func navigationBarFadeAndMoveIn()
16
-    func navigationBarFadeAndMoveOut()
13
+    func navigationBarFadeIn(percentage: CGFloat)
14
+    func navigationBarFadeOut(percentage: CGFloat)
15
+    func navigationBarFadeAndMoveIn(percentage: CGFloat)
16
+    func navigationBarFadeAndMoveOut(percentage: CGFloat)
17 17
     func navigationBarFadeOutWithPercentage(_ percentage: CGFloat)
18 18
     func navigationBarFadeInWithPercentage(_ percentage: CGFloat)
19 19
 }
20 20
 
21 21
 public extension NavigationBarInOutAnimator where Self: UIViewController & NavigationBarPushAndPopDelegate {
22
-    func navigationBarFadeIn() {
23
-        UIView.animate(withDuration: 0.3, animations: {
22
+    func navigationBarFadeIn(percentage: CGFloat) {
23
+        UIView.animate(withDuration: TimeInterval(0.3 * percentage),
24
+                       animations: {
24 25
             self.navigationView.alpha = 1
25 26
         }, completion: nil)
26 27
     }
27 28
     
28
-    func navigationBarFadeOut() {
29
-        UIView.animate(withDuration: 0.3, animations: {
29
+    func navigationBarFadeOut(percentage: CGFloat) {
30
+        UIView.animate(withDuration: TimeInterval(0.3 * percentage),
31
+                       animations: {
30 32
             self.navigationView.alpha = 0
31 33
         }, completion: nil)
32 34
     }
33 35
     
34
-    func navigationBarFadeAndMoveIn() {
35
-        setNavigationBar()
36
-        navigationController?.navigationBar.layoutIfNeeded()
36
+    func navigationBarFadeAndMoveIn(percentage: CGFloat) {
37
+//        setNavigationBar()
38
+//        navigationController?.navigationBar.layoutIfNeeded()
37 39
         
38
-        let originX = navigationView.center.x
39
-        navigationView.center.x = UIScreen.main.bounds.width
40
+//        let originX = navigationView.center.x
41
+//        navigationView.center.x = UIScreen.main.bounds.width
40 42
         
41
-        UIView.animate(withDuration: 0.3, animations: {
43
+        UIView.animate(withDuration: TimeInterval(0.3 * percentage),
44
+                       animations: {
42 45
             self.navigationView.alpha = 1
43
-            self.navigationView.center.x = originX
44
-        }, completion: nil)
46
+            self.navigationView.center.x = UIScreen.main.bounds.width / 2
47
+        }, completion: { flag in
48
+//            if flag {
49
+                self.setNavigationBar()
50
+//            }
51
+            print("move in \(flag)")
52
+        })
45 53
     }
46 54
     
47
-    func navigationBarFadeAndMoveOut() {
48
-        UIView.animate(withDuration: 0.3, animations: {
55
+    func navigationBarFadeAndMoveOut(percentage: CGFloat) {
56
+        print(self.navigationView.center)
57
+        UIView.animate(withDuration: TimeInterval(0.3 * percentage),
58
+                       animations: {
49 59
             self.navigationView.alpha = 0
50 60
             self.navigationView.center.x = UIScreen.main.bounds.width
51
-        }, completion: { _ in
52
-            self.navigationView.removeFromSuperview()
61
+        }, completion: { flag in
62
+//            if flag {
63
+                self.navigationView.removeFromSuperview()
64
+//            }
65
+            print("move out \(flag)")
53 66
         })
54 67
     }
55 68
     

+ 5 - 4
PaiAi/PaiaiUIKit/Reusable/UIKit/NavigationBar/NavigationBarInteractivePopDeletegate.swift

@@ -29,8 +29,9 @@ extension UIViewController {
29 29
         /// navigationController?.visibleViewController == self pop to viewController
30 30
         
31 31
         let percentageAnimation: ((CGFloat) -> Void)
32
-        let fadeInAnimation: (() -> Void)
33
-        let fadeOutAnimation: (() -> Void)
32
+        let fadeInAnimation: ((CGFloat) -> Void)
33
+        let fadeOutAnimation: ((CGFloat) -> Void)
34
+
34 35
         if navigationController == nil {
35 36
             percentageAnimation = self.navigationBarFadeOutWithPercentage
36 37
             fadeInAnimation = self.navigationBarFadeAndMoveIn
@@ -49,10 +50,10 @@ extension UIViewController {
49 50
 
50 51
         if (percentage > 0.5 && navigationController == nil) ||
51 52
             (percentage < 0.5 && navigationController?.visibleViewController == self) {
52
-            fadeOutAnimation()
53
+            fadeOutAnimation(1 - percentage)
53 54
         } else if (percentage < 0.5 && navigationController == nil) ||
54 55
             (percentage > 0.5 && navigationController?.visibleViewController == self) {
55
-            fadeInAnimation()
56
+            fadeInAnimation(percentage)
56 57
         }
57 58
     }
58 59
     

+ 4 - 4
PaiAi/PaiaiUIKit/Reusable/UIKit/NavigationBar/NavigationBarPushAndPopDelegate.swift

@@ -29,11 +29,11 @@ public extension NavigationControllerDelegate where Self: UIViewController {
29 29
                               to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
30 30
         
31 31
         if operation == .push {
32
-            (toVC as? NavigationBarInOutAnimator)?.navigationBarFadeAndMoveIn()
33
-            (fromVC as? NavigationBarInOutAnimator)?.navigationBarFadeOut()
32
+            (toVC as? NavigationBarInOutAnimator)?.navigationBarFadeAndMoveIn(percentage: 1)
33
+            (fromVC as? NavigationBarInOutAnimator)?.navigationBarFadeOut(percentage: 1)
34 34
         } else {
35
-            (toVC as? NavigationBarInOutAnimator)?.navigationBarFadeIn()
36
-            (fromVC as? NavigationBarInOutAnimator)?.navigationBarFadeAndMoveOut()
35
+            (toVC as? NavigationBarInOutAnimator)?.navigationBarFadeIn(percentage: 1)
36
+            (fromVC as? NavigationBarInOutAnimator)?.navigationBarFadeAndMoveOut(percentage: 1)
37 37
         }
38 38
         
39 39
         return nil

+ 29 - 0
PaiAi/PaiaiUIKit/Reusable/UIKit/NavigationController/NavigationController.swift

@@ -0,0 +1,29 @@
1
+//
2
+//  NavigationController.swift
3
+//  PaiaiUIKit
4
+//
5
+//  Created by ffib on 2019/4/3.
6
+//  Copyright © 2019 yb. All rights reserved.
7
+//
8
+
9
+import UIKit
10
+
11
+class NavigationController: UINavigationController {
12
+    
13
+}
14
+
15
+//class NavigationController: UINavigationController {
16
+//
17
+//    override func viewDidLoad() {
18
+//        super.viewDidLoad()
19
+//
20
+//        // Do any additional setup after loading the view.
21
+//    }
22
+//    
23
+//    func set
24
+//}
25
+//
26
+//
27
+//extension UIViewController {
28
+//    n
29
+//}

+ 0 - 1
PaiAi/PaiaiUIKit/Reusable/UIKit/PageViewController/PageViewController.swift

@@ -72,7 +72,6 @@ open class PageViewController: UIViewController {
72 72
         constructViewHierarchy()
73 73
         activateConstraints()
74 74
         setMenuGestureRecognizer()
75
-        setupNavigationBarPushAndPopDelegate()
76 75
         setupNavigationBarInteractivePopDelegate()
77 76
     }
78 77
     

+ 4 - 0
PaiAi/Paiai_iOS/App/Group/GroupViewController.swift

@@ -74,6 +74,10 @@ final class GroupViewController: UIViewController {
74 74
         }
75 75
         collectionView.startRefreshing(at: .top)
76 76
     }
77
+    
78
+    deinit {
79
+        collectionView.endAllRefreshing()
80
+    }
77 81
 }
78 82
 
79 83
 /// UI bindings

+ 4 - 0
PaiAi/Paiai_iOS/App/Home/HomeViewController.swift

@@ -60,6 +60,10 @@ final class HomeViewController: UIViewController {
60 60
             self.viewModel.preload()
61 61
         }
62 62
     }
63
+    
64
+    deinit {
65
+        collectionView.endAllRefreshing()
66
+    }
63 67
 }
64 68
 
65 69
 /// UI bindings

+ 4 - 0
PaiAi/Paiai_iOS/App/Message/MessageListViewController.swift

@@ -88,6 +88,10 @@ final class MessageListViewController: UIViewController {
88 88
         }))
89 89
         presentController(alert)
90 90
     }
91
+    
92
+    deinit {
93
+        tableView.endAllRefreshing()
94
+    }
91 95
 }
92 96
 
93 97
 fileprivate extension MessageListViewController {

+ 4 - 0
PaiAi/Paiai_iOS/App/Mine/MineGroupViewController.swift

@@ -56,6 +56,10 @@ final class MineGroupViewController: UIViewController {
56 56
             self.viewModel.preload()
57 57
         }
58 58
     }
59
+    
60
+    deinit {
61
+        tableView.endAllRefreshing()
62
+    }
59 63
 }
60 64
 
61 65
 fileprivate extension MineGroupViewController {

+ 4 - 0
PaiAi/Paiai_iOS/App/Mine/MineOrderViewController.swift

@@ -53,6 +53,10 @@ final class MineOrderViewController: UIViewController {
53 53
             self.viewModel.preload()
54 54
         }
55 55
     }
56
+    
57
+    deinit {
58
+        tableView.endAllRefreshing()
59
+    }
56 60
 }
57 61
 
58 62
 /// binding UI